DecodeError StructuredHeadersBuffer::parseNumber()

in proxygen/lib/http/structuredheaders/StructuredHeadersBuffer.cpp [43:99]


DecodeError StructuredHeadersBuffer::parseNumber(StructuredHeaderItem& result) {
  auto type = StructuredHeaderItem::Type::INT64;

  bool positive = true;
  std::string input;

  if (isEmpty()) {
    return handleDecodeError(DecodeError::UNEXPECTED_END_OF_BUFFER);
  }

  if (peek() == '-') {
    advanceCursor();
    positive = false;
    input.push_back('-');
  }

  if (isEmpty()) {
    return handleDecodeError(DecodeError::UNEXPECTED_END_OF_BUFFER);
  }

  if (!std::isdigit(peek())) {
    return handleDecodeError(DecodeError::INVALID_CHARACTER);
  }

  while (!isEmpty()) {
    char current = peek();
    if (std::isdigit(current)) {
      input.push_back(current);
      advanceCursor();
    } else if (type == StructuredHeaderItem::Type::INT64 && current == '.') {
      type = StructuredHeaderItem::Type::DOUBLE;
      input.push_back(current);
      advanceCursor();
    } else {
      break;
    }

    int numDigits = input.length() - (positive ? 0 : 1);
    if (type == StructuredHeaderItem::Type::INT64 &&
        numDigits > StructuredHeaders::kMaxValidIntegerLength) {
      return handleDecodeError(DecodeError::VALUE_TOO_LONG);
    } else if (type == StructuredHeaderItem::Type::DOUBLE &&
               numDigits > StructuredHeaders::kMaxValidFloatLength) {
      return handleDecodeError(DecodeError::VALUE_TOO_LONG);
    }
  }

  if (type == StructuredHeaderItem::Type::INT64) {
    return parseInteger(input, result);
  } else if (input.back() == '.') {
    return handleDecodeError(DecodeError::INVALID_CHARACTER);
  } else {
    return parseFloat(input, result);
  }

  return DecodeError::OK;
}