void ResponseFilterWrapper::Filter()

in libcef/browser/net_service/response_filter_wrapper.cc [120:205]


void ResponseFilterWrapper::Filter(const char* data, size_t size) {
  size_t data_in_size = size;
  auto data_in_ptr = data_in_size > 0 ? data : nullptr;

  size_t data_out_offset = 0;
  std::unique_ptr<std::string> data_out;

  while (true) {
    size_t data_in_read = 0;

    if (!data_out) {
      // Start a new buffer. Should have no offset to begin with.
      DCHECK_EQ(0U, data_out_offset);
      data_out = std::make_unique<std::string>();
      data_out->resize(kBufferSize);
    }

    auto data_out_ptr = data_out->data() + data_out_offset;
    size_t data_out_size = kBufferSize - data_out_offset;
    size_t data_out_written = 0;

    last_status_ = filter_->Filter(
        const_cast<char*>(data_in_ptr), data_in_size, data_in_read,
        const_cast<char*>(data_out_ptr), data_out_size, data_out_written);
    if (last_status_ == RESPONSE_FILTER_ERROR)
      break;

    // Validate the out values.
    if (data_in_read > data_in_size) {
      LOG(ERROR) << "potential buffer overflow; data_in_read > data_in_size";
      last_status_ = RESPONSE_FILTER_ERROR;
      break;
    }
    if (data_out_written > data_out_size) {
      LOG(ERROR)
          << "potential buffer overflow; data_out_written > data_out_size";
      last_status_ = RESPONSE_FILTER_ERROR;
      break;
    }
    if (data_out_written == 0 && data_in_read != data_in_size) {
      LOG(ERROR) << "when no data is written all input must be consumed; "
                    "data_out_written == 0 && data_in_read != data_in_size";
      last_status_ = RESPONSE_FILTER_ERROR;
      break;
    }

    if (data_out_written > 0) {
      data_out_offset += data_out_written;
      if (data_out_offset > kBufferSize - kMinBufferSpace) {
        // The buffer is full or almost full. Write the data that we've
        // received so far and start a new buffer.
        data_out->resize(data_out_offset);
        Write(std::move(data_out));
        data_out_offset = 0;
      }
    }

    if (data_in_read < data_in_size) {
      // Keep going until the user reads all data.
      data_in_ptr += data_in_read;
      data_in_size -= data_in_read;
      continue;
    }

    // At this point the user has read all data...
    if (data_in_ptr) {
      // Clear the input buffer.
      data_in_read = data_in_size = 0;
      data_in_ptr = nullptr;
    }

    if (data_out_written == data_out_size &&
        last_status_ == RESPONSE_FILTER_NEED_MORE_DATA) {
      // Output buffer was filled, but data is still pending.
      continue;
    }

    if (data_out_offset > 0) {
      // Write the last of the data that we've received.
      data_out->resize(data_out_offset);
      Write(std::move(data_out));
    }

    break;
  }
}