ParsedContentRange.cpp [plain text]
#include "config.h"
#include "ParsedContentRange.h"
#include <wtf/StdLibExtras.h>
#include <wtf/text/WTFString.h>
namespace WebCore {
static bool areContentRangeValuesValid(int64_t firstBytePosition, int64_t lastBytePosition, int64_t instanceLength)
{
if (firstBytePosition < 0)
return false;
if (lastBytePosition < firstBytePosition)
return false;
if (instanceLength == ParsedContentRange::UnknownLength)
return true;
return lastBytePosition < instanceLength;
}
static bool parseContentRange(const String& headerValue, int64_t& firstBytePosition, int64_t& lastBytePosition, int64_t& instanceLength)
{
static const char* prefix = "bytes ";
static const size_t prefixLength = 6;
if (!headerValue.startsWith(prefix))
return false;
size_t byteSeparatorTokenLoc = headerValue.find('-', prefixLength);
if (byteSeparatorTokenLoc == notFound)
return false;
size_t instanceLengthSeparatorToken = headerValue.find('/', byteSeparatorTokenLoc + 1);
if (instanceLengthSeparatorToken == notFound)
return false;
bool isOk = true;
String firstByteString = headerValue.substring(prefixLength, byteSeparatorTokenLoc - prefixLength);
if (!firstByteString.isAllSpecialCharacters<isASCIIDigit>())
return false;
firstBytePosition = firstByteString.toInt64Strict(&isOk);
if (!isOk)
return false;
String lastByteString = headerValue.substring(byteSeparatorTokenLoc + 1, instanceLengthSeparatorToken - (byteSeparatorTokenLoc + 1));
if (!lastByteString.isAllSpecialCharacters<isASCIIDigit>())
return false;
lastBytePosition = lastByteString.toInt64Strict(&isOk);
if (!isOk)
return false;
String instanceString = headerValue.substring(instanceLengthSeparatorToken + 1);
if (instanceString == "*")
instanceLength = ParsedContentRange::UnknownLength;
else {
if (!instanceString.isAllSpecialCharacters<isASCIIDigit>())
return false;
instanceLength = instanceString.toInt64Strict(&isOk);
if (!isOk)
return false;
}
return areContentRangeValuesValid(firstBytePosition, lastBytePosition, instanceLength);
}
ParsedContentRange::ParsedContentRange(const String& headerValue)
{
m_isValid = parseContentRange(headerValue, m_firstBytePosition, m_lastBytePosition, m_instanceLength);
}
ParsedContentRange::ParsedContentRange(int64_t firstBytePosition, int64_t lastBytePosition, int64_t instanceLength)
: m_firstBytePosition(firstBytePosition)
, m_lastBytePosition(lastBytePosition)
, m_instanceLength(instanceLength)
{
m_isValid = areContentRangeValuesValid(m_firstBytePosition, m_lastBytePosition, m_instanceLength);
}
String ParsedContentRange::headerValue() const
{
if (!m_isValid)
return String();
if (m_instanceLength == UnknownLength)
return String::format("bytes %" PRId64 "-%" PRId64 "/*", m_firstBytePosition, m_lastBytePosition);
return String::format("bytes %" PRId64 "-%" PRId64 "/%" PRId64, m_firstBytePosition, m_lastBytePosition, m_instanceLength);
}
}