bool RequestParser::ParseMultipartContent(const char* data,
                                          std::size_t length) {
  pending_data_.append(data, length);

  if (!content_length_parsed_ || content_length_ == kInvalidLength) {
    // Invalid content length (syntax error).
    return false;
  }

  while (true) {
    if (pending_data_.empty()) {
      // Wait data from next read.
      break;
    }

    if (step_ == Step::kStart) {
      std::string line;
      if (!GetNextLine(0, &line, true)) {
        break;  // Not enough data
      }
      if (!IsBoundary(line, 0, line.size())) {
        LOG_ERRO("Invalid boundary: %s", line.c_str());
        return false;
      }
      LOG_INFO("Boundary line: %s", line.c_str());
      // Go to next step.
      step_ = Step::kBoundaryParsed;
      continue;
    }

    if (step_ == Step::kBoundaryParsed) {
      if (!part_) {
        part_.reset(new FormPart{});
      }
      bool need_more_data = false;
      if (ParsePartHeaders(&need_more_data)) {
        // Go to next step.
        step_ = Step::kHeadersParsed;
        LOG_INFO("Part headers just ended");
        continue;
      } else {
        if (need_more_data) {
          // Need more data from next read.
          break;
        } else {
          return false;
        }
      }
    }

    if (step_ == Step::kHeadersParsed) {
      std::size_t off = 0;
      std::size_t count = 0;
      bool ended = false;

      // TODO: Remember last CRLF position.
      if (!GetNextBoundaryLine(&off, &count, &ended)) {
        break;
      }

      // Next boundary found.
      LOG_INFO("Next boundary found, off=%u", off);

      // This part has ended.
      if (off >= 2) {
        // -2 for excluding the CRLF after the data.
        part_->AppendData(pending_data_.data(), off - 2);

        // Erase the data of this part and the next boundary.
        // +2 for including the CRLF after the boundary.
        pending_data_.erase(0, off + count + 2);
      } else {
        LOG_ERRO("Invalid part data, off=%u", off);
        return false;
      }

      // Save this part
      form_parts_.push_back(part_);

      // Reset for next part.
      part_.reset();

      if (ended) {
        // Go to the end step.
        step_ = Step::kEnded;
        break;
      } else {
        // Go to next step.
        step_ = Step::kBoundaryParsed;
        continue;
      }
    }
  }

  if (step_ == Step::kEnded) {
    LOG_INFO("Multipart data has ended");

    // Create a body and set to the request.

    auto body = std::make_shared<FormBody>(form_parts_,
                                           content_type_.boundary());

    request_->SetBody(body, false);  // TODO: set_length?

    Finish();
  }

  return true;
}
bool RequestParser::ParseMultipartContent(const char* data,
                                          std::size_t length) {
  pending_data_.append(data, length);

  if (!content_length_parsed_ || content_length_ == kInvalidLength) {
     
    return false;
  }

  while (true) {
    if (pending_data_.empty()) {
       
      break;
    }

    if (step_ == Step::kStart) {
      std::string line;
      if (!GetNextLine(0, &line, true)) {
        break;   
      }
      if (!IsBoundary(line, 0, line.size())) {
        LOG_ERRO("Invalid boundary: %s", line.c_str());
        return false;
      }
      LOG_INFO("Boundary line: %s", line.c_str());
       
      step_ = Step::kBoundaryParsed;
      continue;
    }

    if (step_ == Step::kBoundaryParsed) {
      if (!part_) {
        part_.reset(new FormPart{});
      }
      bool need_more_data = false;
      if (ParsePartHeaders(&need_more_data)) {
         
        step_ = Step::kHeadersParsed;
        LOG_INFO("Part headers just ended");
        continue;
      } else {
        if (need_more_data) {
           
          break;
        } else {
          return false;
        }
      }
    }

    if (step_ == Step::kHeadersParsed) {
      std::size_t off = 0;
      std::size_t count = 0;
      bool ended = false;

       
      if (!GetNextBoundaryLine(&off, &count, &ended)) {
        break;
      }

       
      LOG_INFO("Next boundary found, off=%u", off);

       
      if (off >= 2) {
         
        part_->AppendData(pending_data_.data(), off - 2);

         
         
        pending_data_.erase(0, off + count + 2);
      } else {
        LOG_ERRO("Invalid part data, off=%u", off);
        return false;
      }

       
      form_parts_.push_back(part_);

       
      part_.reset();

      if (ended) {
         
        step_ = Step::kEnded;
        break;
      } else {
         
        step_ = Step::kBoundaryParsed;
        continue;
      }
    }
  }

  if (step_ == Step::kEnded) {
    LOG_INFO("Multipart data has ended");

     

    auto body = std::make_shared<FormBody>(form_parts_,
                                           content_type_.boundary());

    request_->SetBody(body, false);   

    Finish();
  }

  return true;
}