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;
}