Exemplo n.º 1
0
IOBuf::IOBuf(CopyBufferOp op, const void* buf, uint64_t size,
             uint64_t headroom, uint64_t minTailroom)
  : IOBuf(CREATE, headroom + size + minTailroom) {
  advance(headroom);
  memcpy(writableData(), buf, size);
  append(size);
}
Exemplo n.º 2
0
void CompressionCorruptionTest::runSimpleTest(const DataHolder& dh) {
  constexpr uint64_t uncompressedLength = 42;
  auto original = IOBuf::wrapBuffer(dh.data(uncompressedLength));
  auto compressed = codec_->compress(original.get());

  if (!codec_->needsUncompressedLength()) {
    auto uncompressed = codec_->uncompress(compressed.get());
    EXPECT_EQ(uncompressedLength, uncompressed->computeChainDataLength());
    EXPECT_EQ(dh.hash(uncompressedLength), hashIOBuf(uncompressed.get()));
  }
  {
    auto uncompressed = codec_->uncompress(compressed.get(),
                                           uncompressedLength);
    EXPECT_EQ(uncompressedLength, uncompressed->computeChainDataLength());
    EXPECT_EQ(dh.hash(uncompressedLength), hashIOBuf(uncompressed.get()));
  }

  EXPECT_THROW(codec_->uncompress(compressed.get(), uncompressedLength + 1),
               std::runtime_error);

  // Corrupt the first character
  ++(compressed->writableData()[0]);

  if (!codec_->needsUncompressedLength()) {
    EXPECT_THROW(codec_->uncompress(compressed.get()),
                 std::runtime_error);
  }

  EXPECT_THROW(codec_->uncompress(compressed.get(), uncompressedLength),
               std::runtime_error);
}
Exemplo n.º 3
0
fbstring IOBuf::moveToFbString() {
  // malloc-allocated buffers are just fine, everything else needs
  // to be turned into one.
  if (!sharedInfo() ||         // user owned, not ours to give up
      sharedInfo()->freeFn ||  // not malloc()-ed
      headroom() != 0 ||       // malloc()-ed block doesn't start at beginning
      tailroom() == 0 ||       // no room for NUL terminator
      isShared() ||            // shared
      isChained()) {           // chained
    // We might as well get rid of all head and tailroom if we're going
    // to reallocate; we need 1 byte for NUL terminator.
    coalesceAndReallocate(0, computeChainDataLength(), this, 1);
  }

  // Ensure NUL terminated
  *writableTail() = 0;
  fbstring str(reinterpret_cast<char*>(writableData()),
               length(),  capacity(),
               AcquireMallocatedString());

  if (flags() & kFlagFreeSharedInfo) {
    delete sharedInfo();
  }

  // Reset to a state where we can be deleted cleanly
  flagsAndSharedInfo_ = 0;
  buf_ = nullptr;
  clear();
  return str;
}
Exemplo n.º 4
0
std::unique_ptr<folly::IOBuf> FILEReader::operator()(size_t n) {
  auto buf = folly::IOBuf::create(n);
  size_t bytesRead = fread(buf->writableData(), 1, n, fp_);
  if (bytesRead < n) {
    folly::throwSystemError("FILEReader: fread");
  }
  buf->append(n);
  return buf;
}
Exemplo n.º 5
0
std::unique_ptr<IOBuf> ZlibCodec::addOutputBuffer(z_stream* stream,
                                                  uint32_t length) {
  CHECK_EQ(stream->avail_out, 0);

  auto buf = IOBuf::create(length);
  buf->append(length);

  stream->next_out = buf->writableData();
  stream->avail_out = buf->length();

  return buf;
}
Exemplo n.º 6
0
std::unique_ptr<IOBuf> ZSTDCodec::doCompress(const IOBuf* data) {
  // Support earlier versions of the codec (working with a single IOBuf,
  // and using ZSTD_decompress which requires ZSTD frame to contain size,
  // which isn't populated by streaming API).
  if (!data->isChained()) {
    auto out = IOBuf::createCombined(ZSTD_compressBound(data->length()));
    const auto rc = ZSTD_compress(
        out->writableData(),
        out->capacity(),
        data->data(),
        data->length(),
        level_);
    zstdThrowIfError(rc);
    out->append(rc);
    return out;
  }

  auto zcs = ZSTD_createCStream();
  SCOPE_EXIT {
    ZSTD_freeCStream(zcs);
  };

  auto rc = ZSTD_initCStream(zcs, level_);
  zstdThrowIfError(rc);

  Cursor cursor(data);
  auto result = IOBuf::createCombined(ZSTD_compressBound(cursor.totalLength()));

  ZSTD_outBuffer out;
  out.dst = result->writableTail();
  out.size = result->capacity();
  out.pos = 0;

  for (auto buffer = cursor.peekBytes(); !buffer.empty();) {
    ZSTD_inBuffer in;
    in.src = buffer.data();
    in.size = buffer.size();
    for (in.pos = 0; in.pos != in.size;) {
      rc = ZSTD_compressStream(zcs, &out, &in);
      zstdThrowIfError(rc);
    }
    cursor.skip(in.size);
    buffer = cursor.peekBytes();
  }

  rc = ZSTD_endStream(zcs, &out);
  zstdThrowIfError(rc);
  CHECK_EQ(rc, 0);

  result->append(out.pos);
  return result;
}
Exemplo n.º 7
0
std::unique_ptr<IOBuf> ZlibStreamDecompressor::decompress(const IOBuf* in) {
  auto out = IOBuf::create(decompressor_buffer_growth_);
  auto appender = folly::io::Appender(out.get(), decompressor_buffer_growth_);

  const IOBuf* crtBuf = in;
  size_t offset = 0;
  while (true) {
    // Advance to the next IOBuf if necessary
    DCHECK_GE(crtBuf->length(), offset);
    if (crtBuf->length() == offset) {
      crtBuf = crtBuf->next();
      offset = 0;
      if (crtBuf == in) {
        // We hit the end of the IOBuf chain, and are done.
        break;
      }
    }

    if (status_ == Z_STREAM_END) {
      // we convert this into a stream error
      status_ = Z_STREAM_ERROR;
      // we should probably bump up a counter here
      LOG(ERROR) << "error uncompressing buffer: reached end of zlib data "
                    "before the end of the buffer";
      return nullptr;
    }

    // Ensure there is space in the output IOBuf
    appender.ensure(decompressor_buffer_minsize_);
    DCHECK_GT(appender.length(), 0);

    const size_t origAvailIn = crtBuf->length() - offset;
    zlibStream_.next_in = const_cast<uint8_t*>(crtBuf->data() + offset);
    zlibStream_.avail_in = origAvailIn;
    zlibStream_.next_out = appender.writableData();
    zlibStream_.avail_out = appender.length();
    status_ = inflate(&zlibStream_, Z_PARTIAL_FLUSH);
    if (status_ != Z_OK && status_ != Z_STREAM_END) {
      LOG(INFO) << "error uncompressing buffer: r=" << status_;
      return nullptr;
    }

    // Adjust the input offset ahead
    auto inConsumed = origAvailIn - zlibStream_.avail_in;
    offset += inConsumed;
    // Move output buffer ahead
    auto outMove = appender.length() - zlibStream_.avail_out;
    appender.append(outMove);
  }

  return out;
}
Exemplo n.º 8
0
IOBuf::IOBuf(CopyBufferOp /* op */,
             const void* buf,
             uint64_t size,
             uint64_t headroom,
             uint64_t minTailroom)
    : IOBuf(CREATE, headroom + size + minTailroom) {
  advance(headroom);
  if (size > 0) {
    assert(buf != nullptr);
    memcpy(writableData(), buf, size);
    append(size);
  }
}
Exemplo n.º 9
0
/**
 * @details
 * Gets the next chunk of data from the device (if it exists).
 */
void TestChunker::next(QIODevice* device)
{
    // Read data off the device.
    device->open(QIODevice::ReadOnly);
    QByteArray array = device->readAll();
    device->close();
    if (array.size() == 0)
    {
        std::cout << "Nothing to read!" << std::endl;
        return;
    }

    // Get writable data object.
    WritableData writableData(0);
    try
    {
        writableData = getDataStorage(_size);
    }
    catch (const QString& e)
    {
        std::cout << "Unexpected exception: " << e.toStdString() << std::endl;
        return;
    }

    // If the writable data object is not valid, then return.
    if (!writableData.isValid())
        return;

    // ... or, block until writable data is valid.
    while (!writableData.isValid()) {
        writableData = getDataStorage(_size);
        usleep(1);
    }

    // Write some test data.
    writableData.write((void*)array.data(), _size, 0);
}