Esempio n. 1
0
void TZlibTransport::flushToZlib(const uint8_t* buf, int len, int flush) {
  wstream_->next_in  = const_cast<uint8_t*>(buf);
  wstream_->avail_in = len;

  while (true) {
    if (flush == Z_NO_FLUSH && wstream_->avail_in == 0) {
      break;
    }

    // If our ouput buffer is full, flush to the underlying transport.
    if (wstream_->avail_out == 0) {
      transport_->write(cwbuf_, cwbuf_size_);
      wstream_->next_out  = cwbuf_;
      wstream_->avail_out = cwbuf_size_;
    }

    int zlib_rv = deflate(wstream_, flush);

    if (flush == Z_FINISH && zlib_rv == Z_STREAM_END) {
      assert(wstream_->avail_in == 0);
      output_finished_ = true;
      break;
    }

    checkZlibRv(zlib_rv, wstream_->msg);

    if ((flush == Z_SYNC_FLUSH || flush == Z_FULL_FLUSH) &&
        wstream_->avail_in == 0 && wstream_->avail_out != 0) {
      break;
    }
  }
}
Esempio n. 2
0
bool TZlibTransport::readFromZlib() {
  assert(!input_ended_);

  // If we don't have any more compressed data available,
  // read some from the underlying transport.
  if (rstream_->avail_in == 0) {
    uint32_t got = transport_->read(crbuf_, crbuf_size_);
    if (got == 0) {
      return false;
    }
    rstream_->next_in  = crbuf_;
    rstream_->avail_in = got;
  }

  // We have some compressed data now.  Uncompress it.
  int zlib_rv = inflate(rstream_, Z_SYNC_FLUSH);

  if (zlib_rv == Z_STREAM_END) {
    input_ended_ = true;
  } else {
    checkZlibRv(zlib_rv, rstream_->msg);
  }

  return true;
}
Esempio n. 3
0
uint32_t TZlibTransport::read(uint8_t* buf, uint32_t len) {
  int need = len;

  // TODO(dreiss): Skip urbuf on big reads.

  while (true) {
    // Copy out whatever we have available, then give them the min of
    // what we have and what they want, then advance indices.
    int give = std::min(readAvail(), need);
    memcpy(buf, urbuf_ + urpos_, give);
    need -= give;
    buf += give;
    urpos_ += give;

    // If they were satisfied, we are done.
    if (need == 0) {
      return len;
    }

    // If we get to this point, we need to get some more data.

    // If zlib has reported the end of a stream, we can't really do any more.
    if (input_ended_) {
      return len - need;
    }

    // The uncompressed read buffer is empty, so reset the stream fields.
    rstream_->next_out  = urbuf_;
    rstream_->avail_out = urbuf_size_;
    urpos_ = 0;

    // If we don't have any more compressed data available,
    // read some from the underlying transport.
    if (rstream_->avail_in == 0) {
      uint32_t got = transport_->read(crbuf_, crbuf_size_);
      if (got == 0) {
        return len - need;
      }
      rstream_->next_in  = crbuf_;
      rstream_->avail_in = got;
    }

    // We have some compressed data now.  Uncompress it.
    int zlib_rv = inflate(rstream_, Z_SYNC_FLUSH);

    if (zlib_rv == Z_STREAM_END) {
      if (standalone_) {
        input_ended_ = true;
      }
    } else {
      checkZlibRv(zlib_rv, rstream_->msg);
    }

    // Okay.  The read buffer should have whatever we can give it now.
    // Loop back to the start and try to give some more.
  }
}
Esempio n. 4
0
// Don't call this outside of the constructor.
void TZlibTransport::initZlib() {
  int rv;
  bool r_init = false;
  try {
    rstream_ = new z_stream;
    wstream_ = new z_stream;

    rstream_->zalloc = Z_NULL;
    wstream_->zalloc = Z_NULL;
    rstream_->zfree  = Z_NULL;
    wstream_->zfree  = Z_NULL;
    rstream_->opaque = Z_NULL;
    wstream_->opaque = Z_NULL;

    rstream_->next_in   = crbuf_;
    wstream_->next_in   = uwbuf_;
    rstream_->next_out  = urbuf_;
    wstream_->next_out  = cwbuf_;
    rstream_->avail_in  = 0;
    wstream_->avail_in  = 0;
    rstream_->avail_out = urbuf_size_;
    wstream_->avail_out = cwbuf_size_;

    rv = inflateInit(rstream_);
    checkZlibRv(rv, rstream_->msg);

    // Have to set this flag so we know whether to de-initialize.
    r_init = true;

    rv = deflateInit(wstream_, Z_DEFAULT_COMPRESSION);
    checkZlibRv(rv, wstream_->msg);
  }

  catch (...) {
    if (r_init) {
      rv = inflateEnd(rstream_);
      checkZlibRvNothrow(rv, rstream_->msg);
    }
    // There is no way we can get here if wstream_ was initialized.

    throw;
  }
}
Esempio n. 5
0
void TZlibTransport::flushToZlib(const uint8_t* buf, int len, bool finish) {
  int flush = (finish ? Z_FINISH : Z_NO_FLUSH);

  wstream_->next_in  = const_cast<uint8_t*>(buf);
  wstream_->avail_in = len;

  while (wstream_->avail_in > 0 || finish) {
    // If our ouput buffer is full, flush to the underlying transport.
    if (wstream_->avail_out == 0) {
      transport_->write(cwbuf_, cwbuf_size_);
      wstream_->next_out  = cwbuf_;
      wstream_->avail_out = cwbuf_size_;
    }

    int zlib_rv = deflate(wstream_, flush);

    if (finish && zlib_rv == Z_STREAM_END) {
      assert(wstream_->avail_in == 0);
      break;
    }

    checkZlibRv(zlib_rv, wstream_->msg);
  }
}