ParsedContentRange.cpp [plain text]
#include "config.h"
#include "ParsedContentRange.h"
#include <wtf/StdLibExtras.h>
#include <wtf/text/StringConcatenateNumbers.h>
namespace WebCore {
static bool areContentRangeValuesValid(int64_t firstBytePosition, int64_t lastBytePosition, int64_t instanceLength)
{
if (firstBytePosition < 0)
return false;
ASSERT(firstBytePosition >= 0);
if (lastBytePosition < firstBytePosition)
return false;
ASSERT(lastBytePosition >= 0);
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)
{
if (!parseContentRange(headerValue, m_firstBytePosition, m_lastBytePosition, m_instanceLength))
m_instanceLength = invalidLength;
}
ParsedContentRange::ParsedContentRange(int64_t firstBytePosition, int64_t lastBytePosition, int64_t instanceLength)
: m_firstBytePosition(firstBytePosition)
, m_lastBytePosition(lastBytePosition)
, m_instanceLength(instanceLength)
{
if (!areContentRangeValuesValid(m_firstBytePosition, m_lastBytePosition, m_instanceLength))
m_instanceLength = invalidLength;
}
String ParsedContentRange::headerValue() const
{
if (!isValid())
return String();
if (m_instanceLength == unknownLength)
return makeString("bytes ", m_firstBytePosition, '-', m_lastBytePosition, "/*");
return makeString("bytes ", m_firstBytePosition, '-', m_lastBytePosition, '/', m_instanceLength);
}
}