chromium/media/formats/hls/types.h

// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MEDIA_FORMATS_HLS_TYPES_H_
#define MEDIA_FORMATS_HLS_TYPES_H_

#include <cstdint>
#include <optional>

#include "base/containers/span.h"
#include "base/memory/raw_span.h"
#include "base/time/time.h"
#include "media/formats/hls/parse_status.h"
#include "media/formats/hls/source_string.h"
#include "media/formats/hls/variable_dictionary.h"

namespace media::hls::types {

namespace {

template <size_t count, typename impl, typename... types>
struct repeat_t {};

repeat_t<0, impl, types...>;

}  // namespace

// A `DecimalInteger` is an unsigned integer value.
// https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis#:~:text=of%20the%20following%3A%0A%0A%20%20%20o-,decimal%2Dinteger,-%3A%20an%20unquoted%20string
DecimalInteger;

namespace parsing {

// A substituting parser functions as a super-struct parser which provides the
// entry points for raw SourceStrings to either be consumed raw or resolved by
// the sub-struct's Parse method. It is specialized with:
// Subtype: The substruct implementation, which provides the method
//          `static T Parse(ResolvedSourceString, ParseArgs...)`
// T: The type that should result from successful parsing.
// ParseArgs...: Additional arguments that might be passed to the Parse
//               function declared on `Subtype`. For example, some quoted
//               strings are required to be non-empty, so the quoted string
//               parser should have an optional bool parameter to require it.
template <typename Subtype, typename T, typename... ParseArgs>
struct MEDIA_EXPORT SubstitutingParser {};

// A wrapping parser that will parse some other type T which is contained
// withing quotation marks. Quoted<RawStr>::ParseWithoutSubstitution will ensure
// that the SourceString starts and ends with quotation marks, and will return
// a ResolvedSourceString representing the content inside those quotes.
template <typename T>
struct MEDIA_EXPORT Quoted
    : public SubstitutingParser<Quoted<T>, typename T::ParseInto> {};

// Parser struct for a plain ResolvedSourceString. This is usually used
// for things like URIs.
struct MEDIA_EXPORT RawStr : SubstitutingParser<RawStr, ResolvedSourceString> {};

struct MEDIA_EXPORT YesOrNo : SubstitutingParser<YesOrNo, bool> {};

// Parser struct for floating point representations of TimeDelta instances.
struct MEDIA_EXPORT TimeDelta : SubstitutingParser<TimeDelta, base::TimeDelta> {};

// A `ByteRangeExpression` represents the 'length[@offset]' syntax that appears
// in tags describing byte ranges of a resource.
// https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis#section-4.4.4.2
struct MEDIA_EXPORT ByteRangeExpression
    : public SubstitutingParser<ByteRangeExpression, ByteRangeExpression> {};

// Calculate chunk sizes for the hex parser. This needs to be separated so that
// the SubstitutingParser template can be specialized on the proper return type
// of HexRepr::Parse.
template <int64_t bits>
struct HexPackInfo {};

// Represents a hexadecimal string in the form 0xXXXXXX...
// where this might require more than sizeof(size_t) bytes.
// HexRepr<X>::Container can be used to get the tuple format for the
// underlying container that HexRepr<X>::Parse should return.
template <int64_t bits>
struct MEDIA_EXPORT HexRepr
    : public SubstitutingParser<HexRepr<bits>,
                                typename HexPackInfo<bits>::Container> {};

}  // namespace parsing

MEDIA_EXPORT ParseStatus::Or<DecimalInteger> ParseDecimalInteger(
    ResolvedSourceString source_str);

// A `DecimalFloatingPoint` is an unsigned floating-point value.
// https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis#:~:text=on%20its%20AttributeNames.%0A%0A%20%20%20o-,decimal%2Dfloating%2Dpoint,-%3A%20an%20unquoted%20string
DecimalFloatingPoint;

MEDIA_EXPORT ParseStatus::Or<DecimalFloatingPoint> ParseDecimalFloatingPoint(
    ResolvedSourceString source_str);

// A `SignedDecimalFloatingPoint` is a signed floating-point value.
// https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis#:~:text=decimal%20positional%20notation.%0A%0A%20%20%20o-,signed%2Ddecimal%2Dfloating%2Dpoint,-%3A%20an%20unquoted%20string
SignedDecimalFloatingPoint;

MEDIA_EXPORT ParseStatus::Or<SignedDecimalFloatingPoint>
ParseSignedDecimalFloatingPoint(ResolvedSourceString source_str);

// A `DecimalResolution` is a set of two `DecimalInteger`s describing width and
// height.
// https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis#:~:text=enumerated%2Dstring%2Dlist.%0A%0A%20%20%20o-,decimal%2Dresolution,-%3A%20two%20decimal%2Dintegers
struct MEDIA_EXPORT DecimalResolution {};

// This is similar to `ByteRangeExpression`, but with a stronger contract:
// - `length` is non-zero
// - `offset` is non-optional
// - `offset+length` may not overflow `types::DecimalInteger`
class MEDIA_EXPORT ByteRange {};

// Parses a string surrounded by double-quotes ("), returning the inner string.
// These appear in the context of attribute-lists, and are subject to variable
// substitution. `sub_buffer` must outlive the returned string.
// `allow_empty` determines whether an empty quoted string is accepted, (after
// variable substitution) which isn't the case for most attributes.
MEDIA_EXPORT ParseStatus::Or<ResolvedSourceString> ParseQuotedString(
    SourceString source_str,
    const VariableDictionary& variable_dict,
    VariableDictionary::SubstitutionBuffer& sub_buffer,
    bool allow_empty = false);

// Parses a string surrounded by double-quotes ("), returning the interior
// string. These appear in the context of attribute-lists, however certain tags
// disallow variable substitution so this function exists to serve those.
// `allow_empty` determines whether an empty quoted string is accepted, which
// isn't the case for most attributes.
MEDIA_EXPORT ParseStatus::Or<SourceString> ParseQuotedStringWithoutSubstitution(
    SourceString source_str,
    bool allow_empty = false);

// Provides an iterator-style interface over attribute-lists.
// Since the number of attributes expected in an attribute-list for a tag varies
// (most have 2-4, the highest has 15), rather than prescribing a specific data
// structure to use, callers can iterate over the list and build their own.
// `AttributeMap` exists which can match items against a pre-determined set of
// keys, which may be stored on the stack.
struct MEDIA_EXPORT AttributeListIterator {};

// Represents a map of attributes with a fixed set of keys.
// This is essentially a `base::fixed_flat_map`, with the advantage of erasing
// the size of the map from its type.
struct MEDIA_EXPORT AttributeMap {};

// Represents a string that is guaranteed to be a non-empty, and consisting only
// of characters in the set {[a-z], [A-Z], [0-9], _, -}. Variable names are
// case-sensitive.
class MEDIA_EXPORT VariableName {};

// Represents a string that is guaranteed to be non-empty, and consisting only
// of characters in the set {[a-z], [A-Z], [0-9], +, /, =, ., -, _}.
// This is used in the 'STABLE-VARIANT-ID' and 'STABLE-RENDITION-ID' attributes
// of the EXT-X-STREAM-INF and EXT-X-MEDIA tags, respectively.
class MEDIA_EXPORT StableId {};

inline bool operator==(const StableId& lhs, const StableId& rhs) {}
inline bool operator!=(const StableId& lhs, const StableId& rhs) {}
inline bool operator<(const StableId& lhs, const StableId& rhs) {}
inline bool operator>(const StableId& lhs, const StableId& rhs) {}

// Represents the contents of the 'INSTREAM-ID' attribute on the 'EXT-X-MEDIA'
// tag.
class MEDIA_EXPORT InstreamId {};

// Represents the contents of the 'CHANNELS' attribute on the 'EXT-X-MEDIA' tag
// for an audio stream.
// https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis#section-4.4.6.1:~:text=If%20the%20TYPE%20attribute%20is%20AUDIO%2C%20then%20the%20first%20parameter%20is%20a
class MEDIA_EXPORT AudioChannels {};

}  // namespace media::hls::types

#endif  // MEDIA_FORMATS_HLS_TYPES_H_