#include "media/formats/hls/source_string.h"
#include <string_view>
#include "base/strings/string_util.h"
#include "base/types/pass_key.h"
#include "media/formats/hls/parse_status.h"
namespace media::hls {
namespace subtle {
template <typename Self>
Self SourceStringBase<Self>::CreateForTesting(std::string_view str) {
return Self(1, 1, str);
}
template <typename Self>
Self SourceStringBase<Self>::CreateForTesting(size_t line,
size_t column,
std::string_view str) {
return Self(line, column, str);
}
template <typename Self>
Self SourceStringBase<Self>::Substr(size_t pos, size_t count) const {
Self result = static_cast<const Self&>(*this);
result.column_ = column_ + pos;
result.str_ = str_.substr(pos, count);
return result;
}
template <typename Self>
Self SourceStringBase<Self>::Consume(size_t count) {
count = std::min(count, str_.size());
auto consumed = Substr(0, count);
static_cast<Self&>(*this) = Substr(count);
return consumed;
}
template <typename Self>
Self SourceStringBase<Self>::ConsumeDelimiter(char c) {
const auto index = Str().find_first_of(c);
const auto prefix = Consume(index);
Consume(1);
return prefix;
}
template <typename Self>
void SourceStringBase<Self>::TrimStart() {
auto start = Str().find_first_not_of(" \t");
Consume(start);
}
template <typename Self>
void SourceStringBase<Self>::TrimEnd() {
str_ = base::TrimWhitespaceASCII(str_, base::TRIM_TRAILING);
}
template <typename Self>
SourceStringBase<Self>::SourceStringBase(size_t line,
size_t column,
std::string_view str)
: line_(line), column_(column), str_(str) {}
}
SourceString::SourceString(size_t line, size_t column, std::string_view str)
: SourceStringBase(line, column, str) {}
ResolvedSourceString::ResolvedSourceString(size_t line,
size_t column,
std::string_view str,
SubstitutionState substitution_state)
: SourceStringBase(line, column, str),
substitution_state_(substitution_state) {}
ResolvedSourceString SourceString::SkipVariableSubstitution() const {
return ResolvedSourceString::Create(base::PassKey<SourceString>(), Line(),
Column(), Str());
}
ResolvedSourceString::ResolvedSourceString(const ResolvedSourceString& other) =
default;
ResolvedSourceString::ResolvedSourceString(ResolvedSourceString&& other) =
default;
ResolvedSourceString& ResolvedSourceString::operator=(
const ResolvedSourceString& other) = default;
ResolvedSourceString& ResolvedSourceString::operator=(
ResolvedSourceString&& other) = default;
SourceLineIterator::SourceLineIterator(std::string_view source)
: current_line_(1), source_(source) {}
ParseStatus::Or<SourceString> SourceLineIterator::Next() {
if (source_.empty()) {
return ParseStatusCode::kReachedEOF;
}
const auto line_end = source_.find_first_of("\r\n");
if (line_end == std::string_view::npos) {
auto result = SourceString::Create({}, current_line_, source_);
source_ = std::string_view{};
current_line_ += 1;
return result;
}
const auto line_content = source_.substr(0, line_end);
const auto following = source_.substr(line_end);
if (base::StartsWith(following, "\n")) {
source_ = following.substr(1);
} else if (base::StartsWith(following, "\r\n")) {
source_ = following.substr(2);
} else {
return ParseStatusCode::kInvalidEOL;
}
const auto line_number = current_line_;
current_line_ += 1;
return SourceString::Create({}, line_number, line_content);
}
template class MEDIA_EXPORT subtle::SourceStringBase<SourceString>;
template class MEDIA_EXPORT subtle::SourceStringBase<ResolvedSourceString>;
}