1386 lines
56 KiB
C++
1386 lines
56 KiB
C++
// Copyright 2025 Google LLC. All Rights Reserved. This file and proprietary
|
|
// source code may only be used and distributed under the Widevine License
|
|
// Agreement.
|
|
#include "hls_attribute_list.h"
|
|
|
|
#include <inttypes.h>
|
|
|
|
#include <limits>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
#include "string_conversions.h"
|
|
#include "string_utils.h"
|
|
|
|
namespace wvutil {
|
|
namespace test {
|
|
namespace {
|
|
constexpr uint64_t kZeroInt = 0;
|
|
|
|
constexpr uint64_t kMaxInt = std::numeric_limits<uint64_t>::max();
|
|
constexpr char kMaxIntString[] = "18446744073709551615";
|
|
// FYI: 2^52 is the largest float value with whole integer
|
|
// precision.
|
|
constexpr double kMaxIntFloat = 9007199254740992.0;
|
|
constexpr uint64_t kMaxIntFloatInt = 9007199254740992;
|
|
constexpr char kMaxIntFloatString[] = "9007199254740992";
|
|
|
|
} // namespace
|
|
|
|
TEST(HlsAttributeListTest, IsValidName) {
|
|
// Valid attribute names.
|
|
EXPECT_TRUE(HlsAttributeList::IsValidName("METHOD"));
|
|
EXPECT_TRUE(HlsAttributeList::IsValidName("START-DATE"));
|
|
EXPECT_TRUE(HlsAttributeList::IsValidName("SCTE35-CMD"));
|
|
EXPECT_TRUE(HlsAttributeList::IsValidName("SCTE35-IN"));
|
|
EXPECT_TRUE(HlsAttributeList::IsValidName("GROUP-ID"));
|
|
EXPECT_TRUE(HlsAttributeList::IsValidName("X-WIDEVINE-1337"));
|
|
|
|
// Unlikely but still valid.
|
|
EXPECT_TRUE(HlsAttributeList::IsValidName("-"));
|
|
EXPECT_TRUE(HlsAttributeList::IsValidName("-----------"));
|
|
EXPECT_TRUE(HlsAttributeList::IsValidName("123456789"));
|
|
EXPECT_TRUE(HlsAttributeList::IsValidName("-0"));
|
|
|
|
// Invalid attribute names.
|
|
EXPECT_FALSE(HlsAttributeList::IsValidName(""));
|
|
EXPECT_FALSE(HlsAttributeList::IsValidName("lower-case"));
|
|
EXPECT_FALSE(HlsAttributeList::IsValidName("sOME-LOWER-CASE"));
|
|
EXPECT_FALSE(HlsAttributeList::IsValidName("SOME-LOWER-CASe"));
|
|
EXPECT_FALSE(HlsAttributeList::IsValidName("sOME-LOwER-CASE"));
|
|
EXPECT_FALSE(HlsAttributeList::IsValidName("METHOD=NONE"));
|
|
EXPECT_FALSE(HlsAttributeList::IsValidName("WHITE SPACE"));
|
|
EXPECT_FALSE(HlsAttributeList::IsValidName(" WHITE-SPACE"));
|
|
EXPECT_FALSE(HlsAttributeList::IsValidName("WHITE-SPACE "));
|
|
EXPECT_FALSE(HlsAttributeList::IsValidName("NO,COMMA"));
|
|
EXPECT_FALSE(HlsAttributeList::IsValidName("NO\"QUOTE"));
|
|
EXPECT_FALSE(HlsAttributeList::IsValidName("NO\nLF"));
|
|
EXPECT_FALSE(HlsAttributeList::IsValidName("NO\rCR"));
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, IsValidEnumStringValue) {
|
|
// Valid from HLS standard.
|
|
EXPECT_TRUE(HlsAttributeList::IsValidEnumStringValue("NONE"));
|
|
EXPECT_TRUE(HlsAttributeList::IsValidEnumStringValue("AES-128"));
|
|
EXPECT_TRUE(HlsAttributeList::IsValidEnumStringValue("SAMPLE-AES"));
|
|
EXPECT_TRUE(HlsAttributeList::IsValidEnumStringValue("CLOSED-CAPTIONS"));
|
|
EXPECT_TRUE(HlsAttributeList::IsValidEnumStringValue("YES"));
|
|
EXPECT_TRUE(HlsAttributeList::IsValidEnumStringValue("TYPE-0"));
|
|
// Other valid values.
|
|
EXPECT_TRUE(HlsAttributeList::IsValidEnumStringValue("lower-case"));
|
|
EXPECT_TRUE(HlsAttributeList::IsValidEnumStringValue("------"));
|
|
// All punctuation except commas and double quotes.
|
|
EXPECT_TRUE(HlsAttributeList::IsValidEnumStringValue("!@#$%^&*()"));
|
|
EXPECT_TRUE(HlsAttributeList::IsValidEnumStringValue("-=_+{}[]\\|"));
|
|
EXPECT_TRUE(HlsAttributeList::IsValidEnumStringValue(";:'<>./?~`"));
|
|
// Values that look like other types.
|
|
EXPECT_TRUE(HlsAttributeList::IsValidEnumStringValue("1234"));
|
|
EXPECT_TRUE(HlsAttributeList::IsValidEnumStringValue("-12.3"));
|
|
EXPECT_TRUE(HlsAttributeList::IsValidEnumStringValue("0x1234"));
|
|
EXPECT_TRUE(HlsAttributeList::IsValidEnumStringValue("1920x1080"));
|
|
|
|
// Invalid
|
|
EXPECT_FALSE(HlsAttributeList::IsValidEnumStringValue(""));
|
|
EXPECT_FALSE(HlsAttributeList::IsValidEnumStringValue("WHITE SPACE"));
|
|
EXPECT_FALSE(HlsAttributeList::IsValidEnumStringValue(" WHITESPACE"));
|
|
EXPECT_FALSE(HlsAttributeList::IsValidEnumStringValue("WHITESPACE "));
|
|
EXPECT_FALSE(HlsAttributeList::IsValidEnumStringValue("NO,COMMAS"));
|
|
EXPECT_FALSE(HlsAttributeList::IsValidEnumStringValue("NO\"QUOTE"));
|
|
EXPECT_FALSE(HlsAttributeList::IsValidEnumStringValue("NO\nLF"));
|
|
EXPECT_FALSE(HlsAttributeList::IsValidEnumStringValue("NO\rCR"));
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, IsValidQuotedStringValue) {
|
|
// Valid from standard.
|
|
EXPECT_TRUE(HlsAttributeList::IsValidQuotedStringValue(
|
|
"uri:text/plain;base64,SGVsbG8sIFdvcmxkIQ=="));
|
|
EXPECT_TRUE(HlsAttributeList::IsValidQuotedStringValue("com.widevine"));
|
|
EXPECT_TRUE(HlsAttributeList::IsValidQuotedStringValue("1/2/5"));
|
|
EXPECT_TRUE(
|
|
HlsAttributeList::IsValidQuotedStringValue("2024-07-31T11:43:55-12:00"));
|
|
|
|
EXPECT_TRUE(HlsAttributeList::IsValidQuotedStringValue(""));
|
|
EXPECT_TRUE(
|
|
HlsAttributeList::IsValidQuotedStringValue("white space, and commas"));
|
|
|
|
EXPECT_FALSE(HlsAttributeList::IsValidQuotedStringValue("NO\"QUOTE"));
|
|
EXPECT_FALSE(HlsAttributeList::IsValidQuotedStringValue("NO\nLF"));
|
|
EXPECT_FALSE(HlsAttributeList::IsValidQuotedStringValue("NO\rCR"));
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, EmptyList) {
|
|
const HlsAttributeList list;
|
|
constexpr size_t kZero = 0;
|
|
EXPECT_EQ(list.Count(), kZero);
|
|
EXPECT_TRUE(list.IsEmpty());
|
|
const std::vector<std::string> kEmptyVector;
|
|
EXPECT_EQ(list.GetNames(), kEmptyVector);
|
|
EXPECT_FALSE(list.Contains("METHOD"));
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, SetEnumString) {
|
|
HlsAttributeList list;
|
|
EXPECT_TRUE(list.SetEnumString("METHOD", "NONE"));
|
|
EXPECT_TRUE(list.SetEnumString("TYPE", "AUDIO"));
|
|
EXPECT_TRUE(list.SetEnumString("DEFAULT", "NO"));
|
|
// Overwrite.
|
|
EXPECT_TRUE(list.SetEnumString("TYPE", "VIDEO"));
|
|
|
|
EXPECT_EQ(list.Count(), static_cast<size_t>(3));
|
|
EXPECT_TRUE(list.Contains("METHOD"));
|
|
EXPECT_FALSE(list.Contains("AUDIO"));
|
|
|
|
const std::vector<std::string> kExpectedNames = {"DEFAULT", "METHOD", "TYPE"};
|
|
EXPECT_EQ(list.GetNames(), kExpectedNames);
|
|
|
|
std::string value;
|
|
EXPECT_TRUE(list.GetEnumString("METHOD", &value));
|
|
EXPECT_EQ(value, "NONE");
|
|
EXPECT_TRUE(list.GetEnumString("TYPE", &value));
|
|
EXPECT_EQ(value, "VIDEO");
|
|
EXPECT_TRUE(list.GetEnumString("DEFAULT", &value));
|
|
EXPECT_EQ(value, "NO");
|
|
|
|
EXPECT_FALSE(list.GetEnumString("INSTREAM-ID", &value));
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, SetEnumString_Invalid) {
|
|
HlsAttributeList list;
|
|
|
|
EXPECT_FALSE(list.SetEnumString("", "NONE"));
|
|
EXPECT_FALSE(list.SetEnumString("BAD NAME", "NONE"));
|
|
EXPECT_FALSE(list.SetEnumString("bad-name", "NONE"));
|
|
|
|
EXPECT_FALSE(list.SetEnumString("METHOD", ""));
|
|
EXPECT_FALSE(list.SetEnumString("METHOD", "BAD VALUE"));
|
|
EXPECT_FALSE(list.SetEnumString("METHOD", "BAD,VALUE"));
|
|
EXPECT_FALSE(list.SetEnumString("METHOD", "BAD\"VALUE"));
|
|
|
|
EXPECT_TRUE(list.IsEmpty());
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, SetQuotedString) {
|
|
HlsAttributeList list;
|
|
const std::string kUriValue = "uri:text/plain;base64,SGVsbG8sIFdvcmxkIQ==";
|
|
EXPECT_TRUE(list.SetQuotedString("URI", kUriValue));
|
|
EXPECT_TRUE(list.SetQuotedString("VERSION", ""));
|
|
EXPECT_TRUE(list.SetQuotedString("MESSAGE", "Hello, world!"));
|
|
|
|
EXPECT_EQ(list.Count(), static_cast<size_t>(3));
|
|
EXPECT_TRUE(list.Contains("VERSION"));
|
|
EXPECT_FALSE(list.Contains("AUDIO"));
|
|
|
|
const std::vector<std::string> kExpectedNames = {"MESSAGE", "URI", "VERSION"};
|
|
EXPECT_EQ(list.GetNames(), kExpectedNames);
|
|
|
|
std::string value;
|
|
EXPECT_TRUE(list.GetQuotedString("URI", &value));
|
|
EXPECT_EQ(value, kUriValue);
|
|
EXPECT_TRUE(list.GetQuotedString("VERSION", &value));
|
|
EXPECT_EQ(value, "");
|
|
EXPECT_TRUE(list.GetQuotedString("MESSAGE", &value));
|
|
EXPECT_EQ(value, "Hello, world!");
|
|
|
|
EXPECT_FALSE(list.GetQuotedString("INSTREAM-ID", &value));
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, SetQuotedString_Invalid) {
|
|
HlsAttributeList list;
|
|
EXPECT_FALSE(list.SetQuotedString("", "NONE"));
|
|
EXPECT_FALSE(list.SetQuotedString("BAD NAME", "NONE"));
|
|
EXPECT_FALSE(list.SetQuotedString("bad-name", "NONE"));
|
|
|
|
EXPECT_FALSE(list.SetQuotedString("METHOD", "BAD\rVALUE"));
|
|
EXPECT_FALSE(list.SetQuotedString("METHOD", "BAD\nVALUE"));
|
|
EXPECT_FALSE(list.SetQuotedString("METHOD", "BAD\"VALUE"));
|
|
|
|
EXPECT_TRUE(list.IsEmpty());
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, SetHexSequenceAsString) {
|
|
HlsAttributeList list;
|
|
|
|
EXPECT_TRUE(list.SetHexSequence("IV", "some IV value"));
|
|
EXPECT_TRUE(list.SetHexSequence("OTHERWISE-FORBIDDEN", "\r\n \"\b"));
|
|
EXPECT_TRUE(list.SetHexSequence("SMALL", "-"));
|
|
|
|
EXPECT_EQ(list.Count(), static_cast<size_t>(3));
|
|
EXPECT_TRUE(list.Contains("IV"));
|
|
EXPECT_FALSE(list.Contains("AUDIO"));
|
|
|
|
const std::vector<std::string> kExpectedNames = {"IV", "OTHERWISE-FORBIDDEN",
|
|
"SMALL"};
|
|
EXPECT_EQ(list.GetNames(), kExpectedNames);
|
|
|
|
std::string value;
|
|
EXPECT_TRUE(list.GetHexSequence("IV", &value));
|
|
EXPECT_EQ(value, "some IV value");
|
|
EXPECT_TRUE(list.GetHexSequence("OTHERWISE-FORBIDDEN", &value));
|
|
EXPECT_EQ(value, "\r\n \"\b");
|
|
EXPECT_TRUE(list.GetHexSequence("SMALL", &value));
|
|
EXPECT_EQ(value, "-");
|
|
|
|
EXPECT_FALSE(list.GetHexSequence("INSTREAM-ID", &value));
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, SetHexSequenceAsString_Invalid) {
|
|
HlsAttributeList list;
|
|
EXPECT_FALSE(list.SetHexSequence("", "NONE"));
|
|
EXPECT_FALSE(list.SetHexSequence("BAD NAME", "NONE"));
|
|
EXPECT_FALSE(list.SetHexSequence("bad-name", "NONE"));
|
|
|
|
EXPECT_FALSE(list.SetHexSequence("METHOD", ""));
|
|
EXPECT_TRUE(list.IsEmpty());
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, SetHexSequenceAsVector) {
|
|
HlsAttributeList list;
|
|
|
|
const std::vector<uint8_t> kIvValue(16, 0x33);
|
|
EXPECT_TRUE(list.SetHexSequence("IV", kIvValue));
|
|
const std::vector<uint8_t> kSmallValue(1, 0xff);
|
|
EXPECT_TRUE(list.SetHexSequence("SMALL", kSmallValue));
|
|
|
|
EXPECT_EQ(list.Count(), static_cast<size_t>(2));
|
|
EXPECT_TRUE(list.Contains("IV"));
|
|
EXPECT_FALSE(list.Contains("AUDIO"));
|
|
|
|
const std::vector<std::string> kExpectedNames = {"IV", "SMALL"};
|
|
EXPECT_EQ(list.GetNames(), kExpectedNames);
|
|
|
|
std::vector<uint8_t> value;
|
|
EXPECT_TRUE(list.GetHexSequence("IV", &value));
|
|
EXPECT_EQ(value, kIvValue);
|
|
EXPECT_TRUE(list.GetHexSequence("SMALL", &value));
|
|
EXPECT_EQ(value, kSmallValue);
|
|
|
|
EXPECT_FALSE(list.GetHexSequence("INSTREAM-ID", &value));
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, SetHexSequenceAsVector_Invalid) {
|
|
HlsAttributeList list;
|
|
const std::vector<uint8_t> kValidValue(4, 0x20);
|
|
EXPECT_FALSE(list.SetHexSequence("", kValidValue));
|
|
EXPECT_FALSE(list.SetHexSequence("BAD NAME", kValidValue));
|
|
EXPECT_FALSE(list.SetHexSequence("bad-name", kValidValue));
|
|
|
|
const std::vector<uint8_t> kEmptyVector;
|
|
EXPECT_FALSE(list.SetHexSequence("METHOD", kEmptyVector));
|
|
EXPECT_TRUE(list.IsEmpty());
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, SetInteger) {
|
|
HlsAttributeList list;
|
|
const uint64_t kInStreamId = 32;
|
|
EXPECT_TRUE(list.SetInteger("INSTREAM-ID", kInStreamId));
|
|
EXPECT_TRUE(list.SetInteger("ZERO", kZeroInt));
|
|
EXPECT_TRUE(list.SetInteger("MAX", kMaxInt));
|
|
|
|
EXPECT_EQ(list.Count(), static_cast<size_t>(3));
|
|
EXPECT_TRUE(list.Contains("ZERO"));
|
|
EXPECT_FALSE(list.Contains("AUDIO"));
|
|
|
|
const std::vector<std::string> kExpectedNames = {"INSTREAM-ID", "MAX",
|
|
"ZERO"};
|
|
EXPECT_EQ(list.GetNames(), kExpectedNames);
|
|
|
|
uint64_t value = 0;
|
|
EXPECT_TRUE(list.GetInteger("INSTREAM-ID", &value));
|
|
EXPECT_EQ(value, kInStreamId);
|
|
EXPECT_TRUE(list.GetInteger("ZERO", &value));
|
|
EXPECT_EQ(value, kZeroInt);
|
|
EXPECT_TRUE(list.GetInteger("MAX", &value));
|
|
EXPECT_EQ(value, kMaxInt);
|
|
|
|
EXPECT_FALSE(list.GetInteger("VERSION", &value));
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, SetInteger_Invalid) {
|
|
HlsAttributeList list;
|
|
const uint64_t kValidValue = 1337;
|
|
EXPECT_FALSE(list.SetInteger("", kValidValue));
|
|
EXPECT_FALSE(list.SetInteger("BAD NAME", kValidValue));
|
|
EXPECT_FALSE(list.SetInteger("bad-name", kValidValue));
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, SetFloat) {
|
|
HlsAttributeList list;
|
|
const double kFrameRate = 29.97;
|
|
EXPECT_TRUE(list.SetFloat("FRAME-RATE", kFrameRate));
|
|
const double kTimeOffset = -5.5;
|
|
EXPECT_TRUE(list.SetFloat("TIME-OFFSET", kTimeOffset));
|
|
const double kZero = 0.0;
|
|
EXPECT_TRUE(list.SetFloat("ZERO", kZero));
|
|
|
|
EXPECT_EQ(list.Count(), static_cast<size_t>(3));
|
|
EXPECT_TRUE(list.Contains("TIME-OFFSET"));
|
|
EXPECT_FALSE(list.Contains("AUDIO"));
|
|
|
|
const std::vector<std::string> kExpectedNames = {"FRAME-RATE", "TIME-OFFSET",
|
|
"ZERO"};
|
|
EXPECT_EQ(list.GetNames(), kExpectedNames);
|
|
|
|
double value = 0;
|
|
EXPECT_TRUE(list.GetFloat("FRAME-RATE", &value));
|
|
EXPECT_EQ(value, kFrameRate);
|
|
EXPECT_TRUE(list.GetFloat("ZERO", &value));
|
|
EXPECT_EQ(value, kZero);
|
|
EXPECT_TRUE(list.GetFloat("TIME-OFFSET", &value));
|
|
EXPECT_EQ(value, kTimeOffset);
|
|
|
|
EXPECT_FALSE(list.GetFloat("VERSION", &value));
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, SetFloat_Invalid) {
|
|
HlsAttributeList list;
|
|
const double kValidValue = 1337.0;
|
|
EXPECT_FALSE(list.SetFloat("", kValidValue));
|
|
EXPECT_FALSE(list.SetFloat("BAD NAME", kValidValue));
|
|
EXPECT_FALSE(list.SetFloat("bad-name", kValidValue));
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, SetResolution) {
|
|
HlsAttributeList list;
|
|
|
|
EXPECT_TRUE(list.SetResolution("RESOLUTION", 1920, 1080));
|
|
EXPECT_TRUE(list.SetResolution("SVGA-RESOLUTION", 800, 600));
|
|
EXPECT_TRUE(list.SetResolution("NULL-RESOLUTION", 0, 0));
|
|
|
|
const std::vector<std::string> kExpectedNames = {
|
|
"NULL-RESOLUTION", "RESOLUTION", "SVGA-RESOLUTION"};
|
|
EXPECT_EQ(list.GetNames(), kExpectedNames);
|
|
|
|
uint64_t width = 0;
|
|
uint64_t height = 0;
|
|
EXPECT_TRUE(list.GetResolution("RESOLUTION", &width, &height));
|
|
EXPECT_EQ(width, static_cast<uint64_t>(1920));
|
|
EXPECT_EQ(height, static_cast<uint64_t>(1080));
|
|
EXPECT_TRUE(list.GetResolution("NULL-RESOLUTION", &width, &height));
|
|
EXPECT_EQ(width, kZeroInt);
|
|
EXPECT_EQ(height, kZeroInt);
|
|
EXPECT_TRUE(list.GetResolution("SVGA-RESOLUTION", &width, &height));
|
|
EXPECT_EQ(width, static_cast<uint64_t>(800));
|
|
EXPECT_EQ(height, static_cast<uint64_t>(600));
|
|
|
|
EXPECT_FALSE(list.GetResolution("VERSION", &width, &height));
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, SetResolution_Invalid) {
|
|
HlsAttributeList list;
|
|
EXPECT_FALSE(list.SetResolution("", 1920, 1080));
|
|
EXPECT_FALSE(list.SetResolution("BAD NAME", 1920, 1080));
|
|
EXPECT_FALSE(list.SetResolution("bad-name", 1920, 1080));
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, Remove) {
|
|
HlsAttributeList list;
|
|
|
|
EXPECT_TRUE(list.SetEnumString("METHOD", "SAMPLE-AES"));
|
|
EXPECT_TRUE(list.SetQuotedString("VERSION", "1/2/5"));
|
|
const std::vector<uint8_t> kIv(16, 0x42);
|
|
EXPECT_TRUE(list.SetHexSequence("IV", kIv));
|
|
const uint64_t kInStreamId = 32;
|
|
EXPECT_TRUE(list.SetInteger("INSTREAM-ID", kInStreamId));
|
|
const double kFrameRate = 29.97;
|
|
EXPECT_TRUE(list.SetFloat("FRAME-RATE", kFrameRate));
|
|
const uint64_t kWidth = 1920;
|
|
const uint64_t kHeight = 1080;
|
|
EXPECT_TRUE(list.SetResolution("RESOLUTION", kWidth, kHeight));
|
|
|
|
const std::vector<std::string> kExpectedInitialNames = {
|
|
"FRAME-RATE", "INSTREAM-ID", "IV", "METHOD", "RESOLUTION", "VERSION"};
|
|
EXPECT_EQ(list.GetNames(), kExpectedInitialNames);
|
|
|
|
EXPECT_TRUE(list.Remove("IV"));
|
|
EXPECT_TRUE(list.Remove("VERSION"));
|
|
EXPECT_FALSE(list.Remove("TIME-OFFSET"));
|
|
|
|
EXPECT_EQ(list.Count(), static_cast<size_t>(4));
|
|
const std::vector<std::string> kExpectedFinalNames = {
|
|
"FRAME-RATE", "INSTREAM-ID", "METHOD", "RESOLUTION"};
|
|
EXPECT_EQ(list.GetNames(), kExpectedFinalNames);
|
|
|
|
std::string string_value;
|
|
EXPECT_TRUE(list.GetEnumString("METHOD", &string_value));
|
|
EXPECT_EQ(string_value, "SAMPLE-AES");
|
|
EXPECT_FALSE(list.GetEnumString("VERSION", &string_value));
|
|
std::vector<uint8_t> vec_value;
|
|
EXPECT_FALSE(list.GetHexSequence("IV", &vec_value));
|
|
uint64_t int_value = 0;
|
|
EXPECT_TRUE(list.GetInteger("INSTREAM-ID", &int_value));
|
|
EXPECT_EQ(int_value, kInStreamId);
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, AmbiguousValues_EnumStringAsInteger) {
|
|
HlsAttributeList list;
|
|
|
|
EXPECT_TRUE(list.SetEnumString("POSITIVE-INT", "1234"));
|
|
// Max u64 2^64-1
|
|
EXPECT_TRUE(list.SetEnumString("MAX-INT", kMaxIntString));
|
|
EXPECT_TRUE(list.SetEnumString("BIG-ZERO-INT", "00000000000000000000"));
|
|
// Over max, 2^64
|
|
EXPECT_TRUE(list.SetEnumString("OVER-MAX-INT", "18446744073709551616"));
|
|
// Integers cannot be negative
|
|
EXPECT_TRUE(list.SetEnumString("NEGATIVE-INT", "-1337"));
|
|
// Integers cannot use positive sign.
|
|
EXPECT_TRUE(list.SetEnumString("BAD-SIGN", "+42"));
|
|
EXPECT_TRUE(list.SetEnumString("NOT-INT", "OTHER"));
|
|
|
|
EXPECT_TRUE(list.IsType("POSITIVE-INT", HlsAttributeList::kEnumStringType));
|
|
EXPECT_TRUE(list.IsType("POSITIVE-INT", HlsAttributeList::kIntegerType));
|
|
EXPECT_TRUE(list.IsType("MAX-INT", HlsAttributeList::kEnumStringType));
|
|
EXPECT_TRUE(list.IsType("MAX-INT", HlsAttributeList::kIntegerType));
|
|
EXPECT_TRUE(list.IsType("BIG-ZERO-INT", HlsAttributeList::kEnumStringType));
|
|
EXPECT_TRUE(list.IsType("BIG-ZERO-INT", HlsAttributeList::kIntegerType));
|
|
|
|
EXPECT_TRUE(list.IsType("OVER-MAX-INT", HlsAttributeList::kEnumStringType));
|
|
EXPECT_FALSE(list.IsType("OVER-MAX-INT", HlsAttributeList::kIntegerType));
|
|
EXPECT_TRUE(list.IsType("BAD-SIGN", HlsAttributeList::kEnumStringType));
|
|
EXPECT_FALSE(list.IsType("BAD-SIGN", HlsAttributeList::kIntegerType));
|
|
EXPECT_TRUE(list.IsType("NEGATIVE-INT", HlsAttributeList::kEnumStringType));
|
|
EXPECT_FALSE(list.IsType("NEGATIVE-INT", HlsAttributeList::kIntegerType));
|
|
EXPECT_TRUE(list.IsType("NOT-INT", HlsAttributeList::kEnumStringType));
|
|
EXPECT_FALSE(list.IsType("NOT-INT", HlsAttributeList::kIntegerType));
|
|
|
|
uint64_t value = 0;
|
|
EXPECT_TRUE(list.GetInteger("POSITIVE-INT", &value));
|
|
EXPECT_EQ(value, static_cast<uint64_t>(1234));
|
|
EXPECT_TRUE(list.GetInteger("MAX-INT", &value));
|
|
EXPECT_EQ(value, kMaxInt);
|
|
EXPECT_TRUE(list.GetInteger("BIG-ZERO-INT", &value));
|
|
EXPECT_EQ(value, kZeroInt);
|
|
|
|
EXPECT_FALSE(list.GetInteger("OVER-MAX-INT", &value));
|
|
EXPECT_FALSE(list.GetInteger("NEGATIVE-INT", &value));
|
|
EXPECT_FALSE(list.GetInteger("BAD-SIGN", &value));
|
|
EXPECT_FALSE(list.GetInteger("NOT-INT", &value));
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, AmbiguousValues_EnumStringAsFloat) {
|
|
HlsAttributeList list;
|
|
EXPECT_TRUE(list.SetEnumString("POSITIVE-INT", "1234"));
|
|
EXPECT_TRUE(list.SetEnumString("NEGATIVE-INT", "-1337"));
|
|
EXPECT_TRUE(list.SetEnumString("POSITIVE-FLOAT", "29.97"));
|
|
EXPECT_TRUE(list.SetEnumString("NEGATIVE-FLOAT", "-180.0"));
|
|
EXPECT_TRUE(list.SetEnumString("MAX-INT-FLOAT", kMaxIntFloatString));
|
|
EXPECT_TRUE(list.SetEnumString("NO-FRAC", "12."));
|
|
EXPECT_TRUE(list.SetEnumString("NO-INT", ".345"));
|
|
// Floats cannot have positive signs.
|
|
EXPECT_TRUE(list.SetEnumString("BAD-SIGN", "+12.345"));
|
|
EXPECT_TRUE(list.SetEnumString("NOT-FLOAT", "OTHER"));
|
|
|
|
EXPECT_TRUE(list.IsType("POSITIVE-INT", HlsAttributeList::kEnumStringType));
|
|
EXPECT_TRUE(list.IsType("POSITIVE-INT", HlsAttributeList::kFloatType));
|
|
EXPECT_TRUE(list.IsType("NEGATIVE-INT", HlsAttributeList::kEnumStringType));
|
|
EXPECT_TRUE(list.IsType("NEGATIVE-INT", HlsAttributeList::kFloatType));
|
|
EXPECT_TRUE(list.IsType("POSITIVE-FLOAT", HlsAttributeList::kEnumStringType));
|
|
EXPECT_TRUE(list.IsType("POSITIVE-FLOAT", HlsAttributeList::kFloatType));
|
|
EXPECT_TRUE(list.IsType("NEGATIVE-FLOAT", HlsAttributeList::kEnumStringType));
|
|
EXPECT_TRUE(list.IsType("NEGATIVE-FLOAT", HlsAttributeList::kFloatType));
|
|
EXPECT_TRUE(list.IsType("MAX-INT-FLOAT", HlsAttributeList::kEnumStringType));
|
|
EXPECT_TRUE(list.IsType("MAX-INT-FLOAT", HlsAttributeList::kFloatType));
|
|
|
|
EXPECT_TRUE(list.IsType("NO-FRAC", HlsAttributeList::kEnumStringType));
|
|
EXPECT_FALSE(list.IsType("NO-FRAC", HlsAttributeList::kFloatType));
|
|
EXPECT_TRUE(list.IsType("NO-INT", HlsAttributeList::kEnumStringType));
|
|
EXPECT_FALSE(list.IsType("NO-INT", HlsAttributeList::kFloatType));
|
|
EXPECT_TRUE(list.IsType("BAD-SIGN", HlsAttributeList::kEnumStringType));
|
|
EXPECT_FALSE(list.IsType("BAD-SIGN", HlsAttributeList::kFloatType));
|
|
EXPECT_TRUE(list.IsType("NOT-FLOAT", HlsAttributeList::kEnumStringType));
|
|
EXPECT_FALSE(list.IsType("NOT-FLOAT", HlsAttributeList::kFloatType));
|
|
|
|
double value = 0.0;
|
|
EXPECT_TRUE(list.GetFloat("POSITIVE-INT", &value));
|
|
EXPECT_EQ(value, 1234.0);
|
|
EXPECT_TRUE(list.GetFloat("NEGATIVE-INT", &value));
|
|
EXPECT_EQ(value, -1337.0);
|
|
EXPECT_TRUE(list.GetFloat("POSITIVE-FLOAT", &value));
|
|
EXPECT_EQ(value, 29.97);
|
|
EXPECT_TRUE(list.GetFloat("NEGATIVE-FLOAT", &value));
|
|
EXPECT_EQ(value, -180.0);
|
|
EXPECT_TRUE(list.GetFloat("MAX-INT-FLOAT", &value));
|
|
EXPECT_EQ(value, kMaxIntFloat);
|
|
|
|
EXPECT_FALSE(list.GetFloat("NO-FRAC", &value));
|
|
EXPECT_FALSE(list.GetFloat("NO-INT", &value));
|
|
EXPECT_FALSE(list.GetFloat("BAD-SIGN", &value));
|
|
EXPECT_FALSE(list.GetFloat("NOT-FLOAT", &value));
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, AmbiguousValues_EnumStringAsHexSequence) {
|
|
HlsAttributeList list;
|
|
// Hex of "Hello, World!"
|
|
EXPECT_TRUE(list.SetEnumString("VALID-HEX", "0x48656C6C6F2C20576F726C6421"));
|
|
// Hex does not need to be even length.
|
|
EXPECT_TRUE(list.SetEnumString("ODD-HEX", "0X1020304"));
|
|
// Lower case is not valid HLS hex.
|
|
EXPECT_TRUE(
|
|
list.SetEnumString("INVALID-HEX", "0x48656c6c6f2c20576f726c6421"));
|
|
EXPECT_TRUE(list.SetEnumString("NULL-HEX", "0X"));
|
|
EXPECT_TRUE(list.SetEnumString("NOT-HEX", "OTHER"));
|
|
|
|
EXPECT_TRUE(list.IsType("VALID-HEX", HlsAttributeList::kEnumStringType));
|
|
EXPECT_TRUE(list.IsType("VALID-HEX", HlsAttributeList::kHexSequenceType));
|
|
EXPECT_TRUE(list.IsType("ODD-HEX", HlsAttributeList::kEnumStringType));
|
|
EXPECT_TRUE(list.IsType("ODD-HEX", HlsAttributeList::kHexSequenceType));
|
|
|
|
EXPECT_TRUE(list.IsType("INVALID-HEX", HlsAttributeList::kEnumStringType));
|
|
EXPECT_FALSE(list.IsType("INVALID-HEX", HlsAttributeList::kHexSequenceType));
|
|
EXPECT_TRUE(list.IsType("NULL-HEX", HlsAttributeList::kEnumStringType));
|
|
EXPECT_FALSE(list.IsType("NULL-HEX", HlsAttributeList::kHexSequenceType));
|
|
EXPECT_TRUE(list.IsType("NOT-HEX", HlsAttributeList::kEnumStringType));
|
|
EXPECT_FALSE(list.IsType("NOT-HEX", HlsAttributeList::kHexSequenceType));
|
|
|
|
std::string string_value;
|
|
EXPECT_TRUE(list.GetHexSequence("VALID-HEX", &string_value));
|
|
EXPECT_EQ(string_value, "Hello, World!");
|
|
std::vector<uint8_t> vec_value;
|
|
EXPECT_TRUE(list.GetHexSequence("ODD-HEX", &vec_value));
|
|
const std::vector<uint8_t> kOddHexValue = {1, 2, 3, 4};
|
|
EXPECT_EQ(vec_value, kOddHexValue);
|
|
|
|
EXPECT_FALSE(list.GetHexSequence("INVALID-HEX", &string_value));
|
|
EXPECT_FALSE(list.GetHexSequence("NULL-HEX", &string_value));
|
|
EXPECT_FALSE(list.GetHexSequence("NOT-HEX", &string_value));
|
|
|
|
EXPECT_FALSE(list.GetHexSequence("INVALID-HEX", &vec_value));
|
|
EXPECT_FALSE(list.GetHexSequence("NULL-HEX", &vec_value));
|
|
EXPECT_FALSE(list.GetHexSequence("NOT-HEX", &vec_value));
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, AmbiguousValues_EnumStringAsResolution) {
|
|
HlsAttributeList list;
|
|
EXPECT_TRUE(list.SetEnumString("VALID-RES", "1920x1080"));
|
|
EXPECT_TRUE(list.SetEnumString("ZERO-RES", "0x0"));
|
|
const std::string kMaxIntResString =
|
|
std::to_string(kMaxInt) + "x" + std::to_string(kMaxInt);
|
|
EXPECT_TRUE(list.SetEnumString("MAX-RES", kMaxIntResString));
|
|
// Resolution separator must be lower 'x'.
|
|
EXPECT_TRUE(list.SetEnumString("CAP-SEP-RES", "1920X1080"));
|
|
EXPECT_TRUE(list.SetEnumString("MISSING-WIDTH", "x1080"));
|
|
EXPECT_TRUE(list.SetEnumString("MISSING-HEIGHT", "1920x"));
|
|
EXPECT_TRUE(list.SetEnumString("BAD-WIDTH", "BADx1080"));
|
|
EXPECT_TRUE(list.SetEnumString("BAD-HEIGHT", "1920xBAD"));
|
|
EXPECT_TRUE(list.SetEnumString("NOT-RES", "OTHER"));
|
|
|
|
EXPECT_TRUE(list.IsType("VALID-RES", HlsAttributeList::kEnumStringType));
|
|
EXPECT_TRUE(list.IsType("VALID-RES", HlsAttributeList::kResolutionType));
|
|
EXPECT_TRUE(list.IsType("ZERO-RES", HlsAttributeList::kEnumStringType));
|
|
EXPECT_TRUE(list.IsType("ZERO-RES", HlsAttributeList::kResolutionType));
|
|
EXPECT_TRUE(list.IsType("MAX-RES", HlsAttributeList::kEnumStringType));
|
|
EXPECT_TRUE(list.IsType("MAX-RES", HlsAttributeList::kResolutionType));
|
|
|
|
EXPECT_TRUE(list.IsType("CAP-SEP-RES", HlsAttributeList::kEnumStringType));
|
|
EXPECT_FALSE(list.IsType("CAP-SEP-RES", HlsAttributeList::kResolutionType));
|
|
EXPECT_TRUE(list.IsType("MISSING-WIDTH", HlsAttributeList::kEnumStringType));
|
|
EXPECT_FALSE(list.IsType("MISSING-WIDTH", HlsAttributeList::kResolutionType));
|
|
EXPECT_TRUE(list.IsType("MISSING-HEIGHT", HlsAttributeList::kEnumStringType));
|
|
EXPECT_FALSE(
|
|
list.IsType("MISSING-HEIGHT", HlsAttributeList::kResolutionType));
|
|
EXPECT_TRUE(list.IsType("BAD-WIDTH", HlsAttributeList::kEnumStringType));
|
|
EXPECT_FALSE(list.IsType("BAD-WIDTH", HlsAttributeList::kResolutionType));
|
|
EXPECT_TRUE(list.IsType("BAD-HEIGHT", HlsAttributeList::kEnumStringType));
|
|
EXPECT_FALSE(list.IsType("BAD-HEIGHT", HlsAttributeList::kResolutionType));
|
|
EXPECT_TRUE(list.IsType("NOT-RES", HlsAttributeList::kEnumStringType));
|
|
EXPECT_FALSE(list.IsType("NOT-RES", HlsAttributeList::kResolutionType));
|
|
|
|
uint64_t width = 0;
|
|
uint64_t height = 0;
|
|
EXPECT_TRUE(list.GetResolution("VALID-RES", &width, &height));
|
|
EXPECT_EQ(width, static_cast<uint64_t>(1920));
|
|
EXPECT_EQ(height, static_cast<uint64_t>(1080));
|
|
EXPECT_TRUE(list.GetResolution("ZERO-RES", &width, &height));
|
|
EXPECT_EQ(width, kZeroInt);
|
|
EXPECT_EQ(height, kZeroInt);
|
|
EXPECT_TRUE(list.GetResolution("MAX-RES", &width, &height));
|
|
EXPECT_EQ(width, kMaxInt);
|
|
EXPECT_EQ(height, kMaxInt);
|
|
|
|
EXPECT_FALSE(list.GetResolution("CAP-SEP-RES", &width, &height));
|
|
EXPECT_FALSE(list.GetResolution("MISSING-WIDTH", &width, &height));
|
|
EXPECT_FALSE(list.GetResolution("MISSING-HEIGHT", &width, &height));
|
|
EXPECT_FALSE(list.GetResolution("BAD-WIDTH", &width, &height));
|
|
EXPECT_FALSE(list.GetResolution("BAD-HEIGHT", &width, &height));
|
|
EXPECT_FALSE(list.GetResolution("NOT-RES", &width, &height));
|
|
}
|
|
|
|
// Note: All valid hex sequences are also valid enum strings.
|
|
TEST(HlsAttributeListTest, AmbiguousValues_HexSequenceAsEnumString) {
|
|
HlsAttributeList list;
|
|
|
|
const std::vector<uint8_t> kValueData = a2b_hex("DEADBEAF");
|
|
EXPECT_TRUE(list.SetHexSequence("VALUE", kValueData));
|
|
|
|
EXPECT_TRUE(list.IsType("VALUE", HlsAttributeList::kHexSequenceType));
|
|
EXPECT_TRUE(list.IsType("VALUE", HlsAttributeList::kEnumStringType));
|
|
|
|
std::string value;
|
|
EXPECT_TRUE(list.GetEnumString("VALUE", &value));
|
|
// Our implementation will use "0x" prefix.
|
|
EXPECT_EQ(value, "0xDEADBEAF");
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, AmbiguousValues_HexSequenceAsResolution) {
|
|
HlsAttributeList list;
|
|
|
|
const std::vector<uint8_t> kValidResData = a2b_hex("1920");
|
|
EXPECT_TRUE(list.SetHexSequence("VALID-RES", kValidResData));
|
|
const std::vector<uint8_t> kZeroResData = {0};
|
|
EXPECT_TRUE(list.SetHexSequence("ZERO-RES", kZeroResData));
|
|
// Max integer length is 20 (10 bytes -> 20 hex digits)
|
|
const std::vector<uint8_t> kBigZeroResData(10, 0);
|
|
EXPECT_TRUE(list.SetHexSequence("BIG-ZERO-RES", kBigZeroResData));
|
|
const std::vector<uint8_t> kTooBigZeroResData(11, 0);
|
|
EXPECT_TRUE(list.SetHexSequence("TOO-BIG-ZERO-RES", kTooBigZeroResData));
|
|
// Max integer as hex.
|
|
const std::vector<uint8_t> kMaxResData = a2b_hex(kMaxIntString);
|
|
EXPECT_TRUE(list.SetHexSequence("MAX-RES", kMaxResData));
|
|
// Over max as hex.
|
|
const std::vector<uint8_t> kOverMaxResData = a2b_hex("18446744073709551616");
|
|
EXPECT_TRUE(list.SetHexSequence("OVER-MAX-RES", kOverMaxResData));
|
|
// Resolution must be decimal, not hex.
|
|
const std::vector<uint8_t> kNotDecimalResData = a2b_hex("B000");
|
|
EXPECT_TRUE(list.SetHexSequence("NOT-DEC-RES", kNotDecimalResData));
|
|
|
|
EXPECT_TRUE(list.IsType("VALID-RES", HlsAttributeList::kHexSequenceType));
|
|
EXPECT_TRUE(list.IsType("VALID-RES", HlsAttributeList::kResolutionType));
|
|
EXPECT_TRUE(list.IsType("ZERO-RES", HlsAttributeList::kHexSequenceType));
|
|
EXPECT_TRUE(list.IsType("ZERO-RES", HlsAttributeList::kResolutionType));
|
|
EXPECT_TRUE(list.IsType("BIG-ZERO-RES", HlsAttributeList::kHexSequenceType));
|
|
EXPECT_TRUE(list.IsType("BIG-ZERO-RES", HlsAttributeList::kResolutionType));
|
|
EXPECT_TRUE(list.IsType("MAX-RES", HlsAttributeList::kHexSequenceType));
|
|
EXPECT_TRUE(list.IsType("MAX-RES", HlsAttributeList::kResolutionType));
|
|
|
|
EXPECT_TRUE(
|
|
list.IsType("TOO-BIG-ZERO-RES", HlsAttributeList::kHexSequenceType));
|
|
EXPECT_FALSE(
|
|
list.IsType("TOO-BIG-ZERO-RES", HlsAttributeList::kResolutionType));
|
|
EXPECT_TRUE(list.IsType("OVER-MAX-RES", HlsAttributeList::kHexSequenceType));
|
|
EXPECT_FALSE(list.IsType("OVER-MAX-RES", HlsAttributeList::kResolutionType));
|
|
EXPECT_TRUE(list.IsType("NOT-DEC-RES", HlsAttributeList::kHexSequenceType));
|
|
EXPECT_FALSE(list.IsType("NOT-DEC-RES", HlsAttributeList::kResolutionType));
|
|
|
|
uint64_t width = 0;
|
|
uint64_t height = 0;
|
|
EXPECT_TRUE(list.GetResolution("VALID-RES", &width, &height));
|
|
EXPECT_EQ(width, kZeroInt);
|
|
EXPECT_EQ(height, static_cast<uint64_t>(1920));
|
|
EXPECT_TRUE(list.GetResolution("ZERO-RES", &width, &height));
|
|
EXPECT_EQ(width, kZeroInt);
|
|
EXPECT_EQ(height, kZeroInt);
|
|
EXPECT_TRUE(list.GetResolution("BIG-ZERO-RES", &width, &height));
|
|
EXPECT_EQ(width, kZeroInt);
|
|
EXPECT_EQ(height, kZeroInt);
|
|
EXPECT_TRUE(list.GetResolution("MAX-RES", &width, &height));
|
|
EXPECT_EQ(width, kZeroInt);
|
|
EXPECT_EQ(height, kMaxInt);
|
|
|
|
EXPECT_FALSE(list.GetResolution("TOO-BIG-ZERO-RES", &width, &height));
|
|
EXPECT_FALSE(list.GetResolution("OVER-MAX-RES", &width, &height));
|
|
EXPECT_FALSE(list.GetResolution("NOT-DEC-RES", &width, &height));
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, AmbiguousValues_FloatAsInteger) {
|
|
HlsAttributeList list;
|
|
|
|
EXPECT_TRUE(list.SetFloat("ZERO-INT", 0.0));
|
|
EXPECT_TRUE(list.SetFloat("POSITIVE-INT", 123.0));
|
|
EXPECT_TRUE(list.SetFloat("NOT-WHOLE", 123.456));
|
|
EXPECT_TRUE(list.SetFloat("FRAC-ONLY", 0.456));
|
|
EXPECT_TRUE(list.SetFloat("NEGATIVE-INT", -10.0));
|
|
EXPECT_TRUE(list.SetFloat("MAX-FLOAT-INT", kMaxIntFloat));
|
|
|
|
EXPECT_TRUE(list.IsType("ZERO-INT", HlsAttributeList::kFloatType));
|
|
EXPECT_TRUE(list.IsType("ZERO-INT", HlsAttributeList::kIntegerType));
|
|
EXPECT_TRUE(list.IsType("POSITIVE-INT", HlsAttributeList::kFloatType));
|
|
EXPECT_TRUE(list.IsType("POSITIVE-INT", HlsAttributeList::kIntegerType));
|
|
EXPECT_TRUE(list.IsType("MAX-FLOAT-INT", HlsAttributeList::kFloatType));
|
|
EXPECT_TRUE(list.IsType("MAX-FLOAT-INT", HlsAttributeList::kIntegerType));
|
|
|
|
EXPECT_TRUE(list.IsType("NOT-WHOLE", HlsAttributeList::kFloatType));
|
|
EXPECT_FALSE(list.IsType("NOT-WHOLE", HlsAttributeList::kIntegerType));
|
|
EXPECT_TRUE(list.IsType("FRAC-ONLY", HlsAttributeList::kFloatType));
|
|
EXPECT_FALSE(list.IsType("FRAC-ONLY", HlsAttributeList::kIntegerType));
|
|
EXPECT_TRUE(list.IsType("NEGATIVE-INT", HlsAttributeList::kFloatType));
|
|
EXPECT_FALSE(list.IsType("NEGATIVE-INT", HlsAttributeList::kIntegerType));
|
|
|
|
uint64_t value = 0;
|
|
EXPECT_TRUE(list.GetInteger("ZERO-INT", &value));
|
|
EXPECT_EQ(value, kZeroInt);
|
|
EXPECT_TRUE(list.GetInteger("POSITIVE-INT", &value));
|
|
EXPECT_EQ(value, static_cast<uint64_t>(123));
|
|
EXPECT_TRUE(list.GetInteger("MAX-FLOAT-INT", &value));
|
|
EXPECT_EQ(value, kMaxIntFloatInt);
|
|
|
|
EXPECT_FALSE(list.GetInteger("NOT-WHOLE", &value));
|
|
EXPECT_FALSE(list.GetInteger("FRAC-ONLY", &value));
|
|
EXPECT_FALSE(list.GetInteger("NEGATIVE-INT", &value));
|
|
}
|
|
|
|
// Note: All floating point values are valid enum strings.
|
|
TEST(HlsAttributeListTest, AmbiguousValues_FloatAsEnumString) {
|
|
HlsAttributeList list;
|
|
|
|
EXPECT_TRUE(list.SetFloat("ZERO-INT", 0.0));
|
|
EXPECT_TRUE(list.SetFloat("POSITIVE-INT", 123.0));
|
|
EXPECT_TRUE(list.SetFloat("NOT-WHOLE", 123.456));
|
|
EXPECT_TRUE(list.SetFloat("FRAC-ONLY", 0.456));
|
|
EXPECT_TRUE(list.SetFloat("NEGATIVE-INT", -10.0));
|
|
EXPECT_TRUE(list.SetFloat("MAX-FLOAT-INT", kMaxIntFloat));
|
|
|
|
EXPECT_TRUE(list.IsType("ZERO-INT", HlsAttributeList::kFloatType));
|
|
EXPECT_TRUE(list.IsType("ZERO-INT", HlsAttributeList::kEnumStringType));
|
|
EXPECT_TRUE(list.IsType("POSITIVE-INT", HlsAttributeList::kFloatType));
|
|
EXPECT_TRUE(list.IsType("POSITIVE-INT", HlsAttributeList::kEnumStringType));
|
|
EXPECT_TRUE(list.IsType("MAX-FLOAT-INT", HlsAttributeList::kFloatType));
|
|
EXPECT_TRUE(list.IsType("MAX-FLOAT-INT", HlsAttributeList::kEnumStringType));
|
|
EXPECT_TRUE(list.IsType("NOT-WHOLE", HlsAttributeList::kFloatType));
|
|
EXPECT_TRUE(list.IsType("NOT-WHOLE", HlsAttributeList::kEnumStringType));
|
|
EXPECT_TRUE(list.IsType("FRAC-ONLY", HlsAttributeList::kFloatType));
|
|
EXPECT_TRUE(list.IsType("FRAC-ONLY", HlsAttributeList::kEnumStringType));
|
|
EXPECT_TRUE(list.IsType("NEGATIVE-INT", HlsAttributeList::kFloatType));
|
|
EXPECT_TRUE(list.IsType("NEGATIVE-INT", HlsAttributeList::kEnumStringType));
|
|
|
|
std::string value;
|
|
EXPECT_TRUE(list.GetEnumString("ZERO-INT", &value));
|
|
EXPECT_EQ(value, "0");
|
|
EXPECT_TRUE(list.GetEnumString("POSITIVE-INT", &value));
|
|
EXPECT_EQ(value, "123");
|
|
EXPECT_TRUE(list.GetEnumString("NOT-WHOLE", &value));
|
|
EXPECT_EQ(value, "123.456");
|
|
EXPECT_TRUE(list.GetEnumString("FRAC-ONLY", &value));
|
|
EXPECT_EQ(value, "0.456");
|
|
EXPECT_TRUE(list.GetEnumString("NEGATIVE-INT", &value));
|
|
EXPECT_EQ(value, "-10");
|
|
EXPECT_TRUE(list.GetEnumString("MAX-FLOAT-INT", &value));
|
|
EXPECT_EQ(value, kMaxIntFloatString);
|
|
}
|
|
|
|
// Note: All integers values are valid enum strings.
|
|
TEST(HlsAttributeListTest, AmbiguousValues_IntegerAsEnumString) {
|
|
HlsAttributeList list;
|
|
|
|
EXPECT_TRUE(list.SetInteger("ZERO-INT", kZeroInt));
|
|
EXPECT_TRUE(list.SetInteger("SOME-INT", 123456));
|
|
EXPECT_TRUE(list.SetInteger("MAX-INT", kMaxInt));
|
|
|
|
EXPECT_TRUE(list.IsType("ZERO-INT", HlsAttributeList::kIntegerType));
|
|
EXPECT_TRUE(list.IsType("ZERO-INT", HlsAttributeList::kEnumStringType));
|
|
EXPECT_TRUE(list.IsType("SOME-INT", HlsAttributeList::kIntegerType));
|
|
EXPECT_TRUE(list.IsType("SOME-INT", HlsAttributeList::kEnumStringType));
|
|
EXPECT_TRUE(list.IsType("MAX-INT", HlsAttributeList::kIntegerType));
|
|
EXPECT_TRUE(list.IsType("MAX-INT", HlsAttributeList::kEnumStringType));
|
|
|
|
std::string value;
|
|
EXPECT_TRUE(list.GetEnumString("ZERO-INT", &value));
|
|
EXPECT_EQ(value, "0");
|
|
EXPECT_TRUE(list.GetEnumString("SOME-INT", &value));
|
|
EXPECT_EQ(value, "123456");
|
|
EXPECT_TRUE(list.GetEnumString("MAX-INT", &value));
|
|
EXPECT_EQ(value, kMaxIntString);
|
|
}
|
|
|
|
// Note: All integer values appear as valid float values;
|
|
// however, double-precision floats have limited range.
|
|
TEST(HlsAttributeListTest, AmbiguousValues_IntegerAsFloat) {
|
|
HlsAttributeList list;
|
|
|
|
EXPECT_TRUE(list.SetInteger("ZERO-INT", kZeroInt));
|
|
EXPECT_TRUE(list.SetInteger("SOME-INT", 123456));
|
|
EXPECT_TRUE(list.SetInteger("MAX-INT-FLOAT", kMaxIntFloat));
|
|
|
|
EXPECT_TRUE(list.IsType("ZERO-INT", HlsAttributeList::kIntegerType));
|
|
EXPECT_TRUE(list.IsType("ZERO-INT", HlsAttributeList::kFloatType));
|
|
EXPECT_TRUE(list.IsType("SOME-INT", HlsAttributeList::kIntegerType));
|
|
EXPECT_TRUE(list.IsType("SOME-INT", HlsAttributeList::kFloatType));
|
|
EXPECT_TRUE(list.IsType("MAX-INT-FLOAT", HlsAttributeList::kIntegerType));
|
|
EXPECT_TRUE(list.IsType("MAX-INT-FLOAT", HlsAttributeList::kFloatType));
|
|
|
|
double value;
|
|
EXPECT_TRUE(list.GetFloat("ZERO-INT", &value));
|
|
EXPECT_EQ(value, 0.0);
|
|
EXPECT_TRUE(list.GetFloat("SOME-INT", &value));
|
|
EXPECT_EQ(value, 123456);
|
|
EXPECT_TRUE(list.GetFloat("MAX-INT-FLOAT", &value));
|
|
EXPECT_EQ(value, kMaxIntFloat);
|
|
}
|
|
|
|
// Note: All resolutions are valid enum strings.
|
|
TEST(HlsAttributeListTest, AmbiguousValues_ResolutionAsEnumString) {
|
|
HlsAttributeList list;
|
|
|
|
EXPECT_TRUE(list.SetResolution("ZERO-RES", kZeroInt, kZeroInt));
|
|
EXPECT_TRUE(list.SetResolution("RESOLUTION", 1920, 1080));
|
|
EXPECT_TRUE(list.SetResolution("MAX-RES", kMaxInt, kMaxInt));
|
|
|
|
EXPECT_TRUE(list.IsType("ZERO-RES", HlsAttributeList::kResolutionType));
|
|
EXPECT_TRUE(list.IsType("ZERO-RES", HlsAttributeList::kEnumStringType));
|
|
EXPECT_TRUE(list.IsType("RESOLUTION", HlsAttributeList::kResolutionType));
|
|
EXPECT_TRUE(list.IsType("RESOLUTION", HlsAttributeList::kEnumStringType));
|
|
EXPECT_TRUE(list.IsType("MAX-RES", HlsAttributeList::kResolutionType));
|
|
EXPECT_TRUE(list.IsType("MAX-RES", HlsAttributeList::kEnumStringType));
|
|
|
|
std::string value;
|
|
EXPECT_TRUE(list.GetEnumString("ZERO-RES", &value));
|
|
EXPECT_EQ(value, "0x0");
|
|
EXPECT_TRUE(list.GetEnumString("RESOLUTION", &value));
|
|
EXPECT_EQ(value, "1920x1080");
|
|
EXPECT_TRUE(list.GetEnumString("MAX-RES", &value));
|
|
const std::string kMaxIntResString =
|
|
std::to_string(kMaxInt) + "x" + std::to_string(kMaxInt);
|
|
EXPECT_EQ(value, kMaxIntResString);
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, AmbiguousValues_ResolutionAsHexSequence) {
|
|
HlsAttributeList list;
|
|
|
|
// Note: Only appears are resolution if width is zero.
|
|
EXPECT_TRUE(list.SetResolution("ZERO-RES", kZeroInt, kZeroInt));
|
|
EXPECT_TRUE(list.SetResolution("RESOLUTION", kZeroInt, 1080));
|
|
EXPECT_TRUE(list.SetResolution("MAX-RES", kZeroInt, kMaxInt));
|
|
EXPECT_TRUE(list.SetResolution("NON-ZERO-WIDTH", 1920, 1080));
|
|
|
|
EXPECT_TRUE(list.IsType("ZERO-RES", HlsAttributeList::kResolutionType));
|
|
EXPECT_TRUE(list.IsType("ZERO-RES", HlsAttributeList::kHexSequenceType));
|
|
EXPECT_TRUE(list.IsType("RESOLUTION", HlsAttributeList::kResolutionType));
|
|
EXPECT_TRUE(list.IsType("RESOLUTION", HlsAttributeList::kHexSequenceType));
|
|
EXPECT_TRUE(list.IsType("MAX-RES", HlsAttributeList::kResolutionType));
|
|
EXPECT_TRUE(list.IsType("MAX-RES", HlsAttributeList::kHexSequenceType));
|
|
|
|
EXPECT_TRUE(list.IsType("NON-ZERO-WIDTH", HlsAttributeList::kResolutionType));
|
|
EXPECT_FALSE(
|
|
list.IsType("NON-ZERO-WIDTH", HlsAttributeList::kHexSequenceType));
|
|
|
|
std::vector<uint8_t> value;
|
|
EXPECT_TRUE(list.GetHexSequence("ZERO-RES", &value));
|
|
const std::vector<uint8_t> kZeroResData = {0};
|
|
EXPECT_EQ(value, kZeroResData);
|
|
EXPECT_TRUE(list.GetHexSequence("RESOLUTION", &value));
|
|
const std::vector<uint8_t> kResData = {0x10, 0x80};
|
|
EXPECT_EQ(value, kResData);
|
|
EXPECT_TRUE(list.GetHexSequence("MAX-RES", &value));
|
|
const std::vector<uint8_t> kMaxResData = a2b_hex(kMaxIntString);
|
|
EXPECT_EQ(value, kMaxResData);
|
|
|
|
EXPECT_FALSE(list.GetHexSequence("NON-ZERO-WIDTH", &value));
|
|
}
|
|
|
|
// Quoted strings are always unambiguous.
|
|
TEST(HlsAttributeListTest, UnambiguousValues_QuotedStringAsAnything) {
|
|
HlsAttributeList list;
|
|
|
|
// Settings to quoted values of otherwise valid types.
|
|
EXPECT_TRUE(list.SetQuotedString("INT-LIKE", "1234"));
|
|
EXPECT_TRUE(list.SetQuotedString("FLOAT-LIKE", "-12.34"));
|
|
EXPECT_TRUE(list.SetQuotedString("ENUM-LIKE", "VALUE"));
|
|
EXPECT_TRUE(list.SetQuotedString("RES-LIKE", "1920x1080"));
|
|
EXPECT_TRUE(list.SetQuotedString("HEX-LIKE", "0xDEADBEAF"));
|
|
|
|
const std::vector<HlsAttributeList::ValueType> kNonQuotedStringTypes = {
|
|
HlsAttributeList::kIntegerType, HlsAttributeList::kFloatType,
|
|
HlsAttributeList::kEnumStringType, HlsAttributeList::kResolutionType,
|
|
HlsAttributeList::kHexSequenceType};
|
|
|
|
const std::vector<std::string> names = list.GetNames();
|
|
const std::vector<std::string> kExpectedNames = {
|
|
"ENUM-LIKE", "FLOAT-LIKE", "HEX-LIKE", "INT-LIKE", "RES-LIKE"};
|
|
// Validity check, if this fails, something other that what
|
|
// this test is checking for has failed.
|
|
ASSERT_EQ(names, kExpectedNames);
|
|
|
|
for (const auto& name : names) {
|
|
EXPECT_TRUE(list.IsType(name, HlsAttributeList::kQuotedStringType))
|
|
<< "name = " << name;
|
|
for (const auto& type : kNonQuotedStringTypes) {
|
|
EXPECT_FALSE(list.IsType(name, type))
|
|
<< "name = " << name
|
|
<< ", type = " << HlsAttributeList::ValueTypeToString(type);
|
|
}
|
|
}
|
|
|
|
// Accessor test for only similar looking types.
|
|
uint64_t int_value = 0;
|
|
EXPECT_FALSE(list.GetInteger("INT-LIKE", &int_value));
|
|
double float_value = 0.0;
|
|
EXPECT_FALSE(list.GetFloat("FLOAT-LIKE", &float_value));
|
|
std::string string_value;
|
|
EXPECT_FALSE(list.GetEnumString("ENUM-LIKE", &string_value));
|
|
EXPECT_FALSE(list.GetHexSequence("HEX-LIKE", &string_value));
|
|
std::vector<uint8_t> vec_value;
|
|
EXPECT_FALSE(list.GetHexSequence("HEX-LIKE", &vec_value));
|
|
uint64_t other_int_value = 0;
|
|
EXPECT_FALSE(list.GetResolution("RES-LIKE", &int_value, &other_int_value));
|
|
}
|
|
|
|
// Nothing can appear as a quoted string.
|
|
TEST(HlsAttributeListTest, UnambiguousValues_AnythingAsQuotedString) {
|
|
HlsAttributeList list;
|
|
|
|
EXPECT_TRUE(list.SetInteger("INT", 1234));
|
|
EXPECT_TRUE(list.SetHexSequence("HEX", "data"));
|
|
EXPECT_TRUE(list.SetEnumString("ENUM", "VALUE"));
|
|
EXPECT_TRUE(list.SetFloat("FLOAT", 12.34));
|
|
EXPECT_TRUE(list.SetResolution("RESOLUTION", 1920, 1080));
|
|
|
|
const std::vector<HlsAttributeList::ValueType> kNonQuotedStringTypes = {
|
|
HlsAttributeList::kIntegerType, HlsAttributeList::kFloatType,
|
|
HlsAttributeList::kEnumStringType, HlsAttributeList::kResolutionType,
|
|
HlsAttributeList::kHexSequenceType};
|
|
|
|
const std::vector<std::string> names = list.GetNames();
|
|
const std::vector<std::string> kExpectedNames = {"ENUM", "FLOAT", "HEX",
|
|
"INT", "RESOLUTION"};
|
|
// Validity check, if this fails, something other that what
|
|
// this test is checking for has failed.
|
|
ASSERT_EQ(names, kExpectedNames);
|
|
|
|
for (const auto& name : names) {
|
|
EXPECT_FALSE(list.IsType(name, HlsAttributeList::kQuotedStringType))
|
|
<< "name = " << name;
|
|
std::string value;
|
|
EXPECT_FALSE(list.GetQuotedString(name, &value));
|
|
}
|
|
}
|
|
|
|
// Integers can never appear are hex sequences or resolutions.
|
|
// Note: Also quoted strings, tested above.
|
|
TEST(HlsAttributeListTest, UnambiguousValues_Integer) {
|
|
HlsAttributeList list;
|
|
|
|
EXPECT_TRUE(list.SetInteger("ZERO-INT", kZeroInt));
|
|
EXPECT_TRUE(list.SetInteger("SOME-INT", 1234));
|
|
EXPECT_TRUE(list.SetInteger("MAX-INT", kMaxInt));
|
|
|
|
const std::vector<std::string> names = list.GetNames();
|
|
ASSERT_EQ(names.size(), static_cast<size_t>(3));
|
|
|
|
for (const auto& name : names) {
|
|
EXPECT_TRUE(list.IsType(name, HlsAttributeList::kIntegerType))
|
|
<< "name = " << name;
|
|
EXPECT_FALSE(list.IsType(name, HlsAttributeList::kHexSequenceType))
|
|
<< "name = " << name;
|
|
EXPECT_FALSE(list.IsType(name, HlsAttributeList::kResolutionType))
|
|
<< "name = " << name;
|
|
|
|
std::string string_value;
|
|
EXPECT_FALSE(list.GetHexSequence(name, &string_value)) << "name = " << name;
|
|
std::vector<uint8_t> vec_value;
|
|
EXPECT_FALSE(list.GetHexSequence(name, &vec_value)) << "name = " << name;
|
|
uint64_t width = 0;
|
|
uint64_t height = 0;
|
|
EXPECT_FALSE(list.GetResolution(name, &width, &height))
|
|
<< "name = " << name;
|
|
}
|
|
}
|
|
|
|
// Hex sequences can never appear as integers or floats.
|
|
// Note: Also quoted strings, tested above.
|
|
TEST(HlsAttributeListTest, UnambiguousValues_HexSequence) {
|
|
HlsAttributeList list;
|
|
|
|
const std::vector<uint8_t> kSmallZeroData = {0};
|
|
EXPECT_TRUE(list.SetHexSequence("SMALL-ZERO", kSmallZeroData));
|
|
const std::vector<uint8_t> kBigZeroData(10, 0);
|
|
EXPECT_TRUE(list.SetHexSequence("BIG-ZERO", kBigZeroData));
|
|
const std::vector<uint8_t> kDecimalData = a2b_hex("1234");
|
|
EXPECT_TRUE(list.SetHexSequence("DEC", kDecimalData));
|
|
const std::vector<uint8_t> kHexData = a2b_hex("deadbeaf");
|
|
EXPECT_TRUE(list.SetHexSequence("HEX", kHexData));
|
|
|
|
const std::vector<std::string> names = list.GetNames();
|
|
ASSERT_EQ(names.size(), static_cast<size_t>(4));
|
|
|
|
for (const auto& name : names) {
|
|
EXPECT_TRUE(list.IsType(name, HlsAttributeList::kHexSequenceType))
|
|
<< "name = " << name;
|
|
EXPECT_FALSE(list.IsType(name, HlsAttributeList::kIntegerType))
|
|
<< "name = " << name;
|
|
EXPECT_FALSE(list.IsType(name, HlsAttributeList::kFloatType))
|
|
<< "name = " << name;
|
|
|
|
uint64_t int_value = 0;
|
|
EXPECT_FALSE(list.GetInteger(name, &int_value)) << "name = " << name;
|
|
double float_value = 0.0;
|
|
EXPECT_FALSE(list.GetFloat(name, &float_value)) << "name = " << name;
|
|
}
|
|
}
|
|
|
|
// Floats can never appear as hex sequences or resolutions.
|
|
// Note: Also quoted strings, tested above.
|
|
TEST(HlsAttributeListTest, UnambiguousValues_Float) {
|
|
HlsAttributeList list;
|
|
|
|
EXPECT_TRUE(list.SetFloat("ZERO", 0.0));
|
|
EXPECT_TRUE(list.SetFloat("MAX-INT-FLOAT", kMaxIntFloat));
|
|
EXPECT_TRUE(list.SetFloat("SOME-FLOAT", 12.34));
|
|
|
|
const std::vector<std::string> names = list.GetNames();
|
|
ASSERT_EQ(names.size(), static_cast<size_t>(3));
|
|
|
|
for (const auto& name : names) {
|
|
EXPECT_TRUE(list.IsType(name, HlsAttributeList::kFloatType))
|
|
<< "name = " << name;
|
|
EXPECT_FALSE(list.IsType(name, HlsAttributeList::kHexSequenceType))
|
|
<< "name = " << name;
|
|
EXPECT_FALSE(list.IsType(name, HlsAttributeList::kResolutionType))
|
|
<< "name = " << name;
|
|
|
|
std::string string_value;
|
|
EXPECT_FALSE(list.GetHexSequence(name, &string_value)) << "name = " << name;
|
|
std::vector<uint8_t> vec_value;
|
|
EXPECT_FALSE(list.GetHexSequence(name, &vec_value)) << "name = " << name;
|
|
uint64_t width = 0;
|
|
uint64_t height = 0;
|
|
EXPECT_FALSE(list.GetResolution(name, &width, &height))
|
|
<< "name = " << name;
|
|
}
|
|
}
|
|
|
|
// Resolutions can never appear as integers or floats.
|
|
// Note: Also quoted strings, tested above.
|
|
TEST(HlsAttributeListTest, UnambiguousValues_Resolution) {
|
|
HlsAttributeList list;
|
|
|
|
EXPECT_TRUE(list.SetResolution("ZERO-RES", kZeroInt, kZeroInt));
|
|
EXPECT_TRUE(list.SetResolution("SOME-RES", 1920, 1080));
|
|
EXPECT_TRUE(list.SetResolution("ZERO-WIDTH-RES", kZeroInt, 1080));
|
|
EXPECT_TRUE(list.SetResolution("ZERO-HEIGHT-RES", 1920, kZeroInt));
|
|
EXPECT_TRUE(list.SetResolution("MAX-RES", kMaxInt, kMaxInt));
|
|
|
|
const std::vector<std::string> names = list.GetNames();
|
|
ASSERT_EQ(names.size(), static_cast<size_t>(5));
|
|
|
|
for (const auto& name : names) {
|
|
EXPECT_TRUE(list.IsType(name, HlsAttributeList::kResolutionType))
|
|
<< "name = " << name;
|
|
EXPECT_FALSE(list.IsType(name, HlsAttributeList::kIntegerType))
|
|
<< "name = " << name;
|
|
EXPECT_FALSE(list.IsType(name, HlsAttributeList::kFloatType))
|
|
<< "name = " << name;
|
|
|
|
uint64_t int_value = 0;
|
|
EXPECT_FALSE(list.GetInteger(name, &int_value)) << "name = " << name;
|
|
double float_value = 0.0;
|
|
EXPECT_FALSE(list.GetFloat(name, &float_value)) << "name = " << name;
|
|
}
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, Parse_SingleInteger) {
|
|
const std::string rep = "INSTREAM-ID=32";
|
|
HlsAttributeList list;
|
|
|
|
EXPECT_TRUE(list.Parse(rep));
|
|
EXPECT_FALSE(list.IsEmpty());
|
|
EXPECT_EQ(list.Count(), static_cast<size_t>(1));
|
|
|
|
const uint64_t kInStreamId = 32;
|
|
uint64_t value = 0;
|
|
EXPECT_TRUE(list.GetInteger("INSTREAM-ID", &value));
|
|
EXPECT_EQ(value, kInStreamId);
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, Parse_SingleFloat) {
|
|
const std::string rep = "FRAME-RATE=29.97";
|
|
HlsAttributeList list;
|
|
|
|
EXPECT_TRUE(list.Parse(rep));
|
|
EXPECT_FALSE(list.IsEmpty());
|
|
EXPECT_EQ(list.Count(), static_cast<size_t>(1));
|
|
|
|
const double kFrameRate = 29.97;
|
|
double value = 0;
|
|
EXPECT_TRUE(list.GetFloat("FRAME-RATE", &value));
|
|
EXPECT_EQ(value, kFrameRate);
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, Parse_SingleEnumString) {
|
|
const std::string rep = "METHOD=AES-128";
|
|
HlsAttributeList list;
|
|
|
|
EXPECT_TRUE(list.Parse(rep));
|
|
EXPECT_FALSE(list.IsEmpty());
|
|
EXPECT_EQ(list.Count(), static_cast<size_t>(1));
|
|
|
|
const std::string kMethod = "AES-128";
|
|
std::string value;
|
|
EXPECT_TRUE(list.GetEnumString("METHOD", &value));
|
|
EXPECT_EQ(value, kMethod);
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, Parse_SingleQuotedString) {
|
|
const std::string rep = "VERSION=\"1/2/5\"";
|
|
HlsAttributeList list;
|
|
|
|
EXPECT_TRUE(list.Parse(rep));
|
|
EXPECT_FALSE(list.IsEmpty());
|
|
EXPECT_EQ(list.Count(), static_cast<size_t>(1));
|
|
|
|
const std::string kVersion = "1/2/5";
|
|
std::string value;
|
|
EXPECT_TRUE(list.GetQuotedString("VERSION", &value));
|
|
EXPECT_EQ(value, kVersion);
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, Parse_SingleEmptyQuotedString) {
|
|
const std::string rep = "KEYFORMAT=\"\"";
|
|
HlsAttributeList list;
|
|
|
|
EXPECT_TRUE(list.Parse(rep));
|
|
EXPECT_FALSE(list.IsEmpty());
|
|
EXPECT_EQ(list.Count(), static_cast<size_t>(1));
|
|
|
|
std::string value = "NOT-EMPTY";
|
|
EXPECT_TRUE(list.GetQuotedString("KEYFORMAT", &value));
|
|
EXPECT_EQ(value, "");
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, Parse_SingleHexSequence) {
|
|
const std::string rep = "IV=0xDEADBEAF";
|
|
HlsAttributeList list;
|
|
|
|
EXPECT_TRUE(list.Parse(rep));
|
|
EXPECT_FALSE(list.IsEmpty());
|
|
EXPECT_EQ(list.Count(), static_cast<size_t>(1));
|
|
|
|
const std::string kIvString = a2bs_hex("DEADBEAF");
|
|
const std::vector<uint8_t> kIvVector(kIvString.begin(), kIvString.end());
|
|
std::string string_value;
|
|
EXPECT_TRUE(list.GetHexSequence("IV", &string_value));
|
|
EXPECT_EQ(string_value, kIvString);
|
|
std::vector<uint8_t> vec_value;
|
|
EXPECT_TRUE(list.GetHexSequence("IV", &vec_value));
|
|
EXPECT_EQ(vec_value, kIvVector);
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, Parse_SingleResolution) {
|
|
const std::string rep = "RESOLUTION=1920x1080";
|
|
HlsAttributeList list;
|
|
|
|
EXPECT_TRUE(list.Parse(rep));
|
|
EXPECT_FALSE(list.IsEmpty());
|
|
EXPECT_EQ(list.Count(), static_cast<size_t>(1));
|
|
|
|
const uint64_t kWidth = 1920;
|
|
const uint64_t kHeight = 1080;
|
|
uint64_t width = 0;
|
|
uint64_t height = 0;
|
|
EXPECT_TRUE(list.GetResolution("RESOLUTION", &width, &height));
|
|
EXPECT_EQ(width, kWidth);
|
|
EXPECT_EQ(height, kHeight);
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, Parse_OneOfEach) {
|
|
const uint64_t kInStreamId = 32;
|
|
const double kFrameRate = 29.97;
|
|
const std::string kIvString = a2bs_hex("DEADBEAF");
|
|
const uint64_t kWidth = 1920;
|
|
const uint64_t kHeight = 1080;
|
|
std::ostringstream hls_stream;
|
|
hls_stream << "INSTREAM-ID=32,";
|
|
hls_stream << "FRAME-RATE=29.97,";
|
|
hls_stream << "METHOD=AES-128,";
|
|
hls_stream << "VERSION=\"1/2/5\",";
|
|
hls_stream << "IV=0xDEADBEAF,";
|
|
hls_stream << "RESOLUTION=1920x1080";
|
|
const std::string rep = hls_stream.str();
|
|
|
|
HlsAttributeList list;
|
|
ASSERT_TRUE(list.Parse(rep));
|
|
|
|
EXPECT_EQ(list.Count(), static_cast<size_t>(6));
|
|
const std::vector<std::string> kExpectedNames = {
|
|
"FRAME-RATE", "INSTREAM-ID", "IV", "METHOD", "RESOLUTION", "VERSION",
|
|
};
|
|
|
|
uint64_t int_value = 0;
|
|
EXPECT_TRUE(list.GetInteger("INSTREAM-ID", &int_value));
|
|
EXPECT_EQ(int_value, kInStreamId);
|
|
double float_value = 0.0;
|
|
EXPECT_TRUE(list.GetFloat("FRAME-RATE", &float_value));
|
|
EXPECT_EQ(float_value, kFrameRate);
|
|
std::string string_value;
|
|
EXPECT_TRUE(list.GetEnumString("METHOD", &string_value));
|
|
EXPECT_EQ(string_value, "AES-128");
|
|
EXPECT_TRUE(list.GetQuotedString("VERSION", &string_value));
|
|
EXPECT_EQ(string_value, "1/2/5");
|
|
EXPECT_TRUE(list.GetHexSequence("IV", &string_value));
|
|
EXPECT_EQ(string_value, kIvString);
|
|
uint64_t other_int_value = 0;
|
|
EXPECT_TRUE(list.GetResolution("RESOLUTION", &int_value, &other_int_value));
|
|
EXPECT_EQ(int_value, kWidth);
|
|
EXPECT_EQ(other_int_value, kHeight);
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, Parse_KeyLike) {
|
|
// #EXT-X-KEY
|
|
const std::string uri = "data:text/plain;base64,SSdtIGEga2V5IQ==";
|
|
std::ostringstream hls_stream;
|
|
hls_stream << "METHOD=AES-128,";
|
|
hls_stream << "URI=\"" << uri << "\",";
|
|
hls_stream << "IV=0xDEADBEAFDEADBEAFDEADBEAFDEADBEAF,";
|
|
hls_stream << "KEYFORMAT=\"com.widevine\",";
|
|
hls_stream << "KEYFORMATVERSIONS=\"1/2/5\"";
|
|
const std::string rep = hls_stream.str();
|
|
|
|
HlsAttributeList list;
|
|
ASSERT_TRUE(list.Parse(rep));
|
|
|
|
EXPECT_EQ(list.Count(), static_cast<size_t>(5));
|
|
const std::vector<std::string> kExpectedNames = {
|
|
"IV", "KEYFORMAT", "KEYFORMATVERSIONS", "METHOD", "URI"};
|
|
EXPECT_EQ(list.GetNames(), kExpectedNames);
|
|
|
|
std::string string_value;
|
|
EXPECT_TRUE(list.GetEnumString("METHOD", &string_value));
|
|
EXPECT_EQ(string_value, "AES-128");
|
|
EXPECT_TRUE(list.GetQuotedString("URI", &string_value));
|
|
EXPECT_EQ(string_value, uri);
|
|
const std::string iv = a2bs_hex("DEADBEAFDEADBEAFDEADBEAFDEADBEAF");
|
|
EXPECT_TRUE(list.GetHexSequence("IV", &string_value));
|
|
EXPECT_EQ(string_value, iv);
|
|
EXPECT_TRUE(list.GetQuotedString("KEYFORMAT", &string_value));
|
|
EXPECT_EQ(string_value, "com.widevine");
|
|
EXPECT_TRUE(list.GetQuotedString("KEYFORMATVERSIONS", &string_value));
|
|
EXPECT_EQ(string_value, "1/2/5");
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, Parse_MediaLike) {
|
|
// #EXT-X-MEDIA
|
|
const std::string uri = "https://media.src/playlist";
|
|
const std::string group_id = "The Best Group";
|
|
const std::string language = "en";
|
|
const std::string associated_language = "fr";
|
|
const std::string name = "The Best Captioning";
|
|
const std::string characteristics = "public.easy-to-read";
|
|
std::ostringstream hls_stream;
|
|
hls_stream << "TYPE=CLOSED-CAPTIONS,";
|
|
hls_stream << "URI=\"" << uri << "\",";
|
|
hls_stream << "GROUP-ID=\"" << group_id << "\",";
|
|
hls_stream << "LANGUAGE=\"" << language << "\",";
|
|
hls_stream << "ASSOC-LANGUAGE=\"" << associated_language << "\",";
|
|
hls_stream << "NAME=\"" << name << "\",";
|
|
hls_stream << "DEFAULT=YES,";
|
|
hls_stream << "AUTOSELECT=NO,";
|
|
hls_stream << "FORCED=NO,";
|
|
hls_stream << "INSTREAM-ID=CC1,";
|
|
hls_stream << "CHARACTERISTICS=\"" << characteristics << "\",";
|
|
hls_stream << "CHANNELS=\"1/2/4/7\"";
|
|
const std::string rep = hls_stream.str();
|
|
|
|
HlsAttributeList list;
|
|
ASSERT_TRUE(list.Parse(rep));
|
|
|
|
EXPECT_EQ(list.Count(), static_cast<size_t>(12));
|
|
const std::vector<std::string> kExpectedNames = {
|
|
"ASSOC-LANGUAGE", "AUTOSELECT", "CHANNELS", "CHARACTERISTICS",
|
|
"DEFAULT", "FORCED", "GROUP-ID", "INSTREAM-ID",
|
|
"LANGUAGE", "NAME", "TYPE", "URI"};
|
|
EXPECT_EQ(list.GetNames(), kExpectedNames);
|
|
|
|
std::string string_value;
|
|
EXPECT_TRUE(list.GetEnumString("TYPE", &string_value));
|
|
EXPECT_EQ(string_value, "CLOSED-CAPTIONS");
|
|
EXPECT_TRUE(list.GetQuotedString("URI", &string_value));
|
|
EXPECT_EQ(string_value, uri);
|
|
EXPECT_TRUE(list.GetQuotedString("GROUP-ID", &string_value));
|
|
EXPECT_EQ(string_value, group_id);
|
|
EXPECT_TRUE(list.GetQuotedString("LANGUAGE", &string_value));
|
|
EXPECT_EQ(string_value, language);
|
|
EXPECT_TRUE(list.GetQuotedString("ASSOC-LANGUAGE", &string_value));
|
|
EXPECT_EQ(string_value, associated_language);
|
|
EXPECT_TRUE(list.GetQuotedString("NAME", &string_value));
|
|
EXPECT_EQ(string_value, name);
|
|
EXPECT_TRUE(list.GetEnumString("DEFAULT", &string_value));
|
|
EXPECT_EQ(string_value, "YES");
|
|
EXPECT_TRUE(list.GetEnumString("AUTOSELECT", &string_value));
|
|
EXPECT_EQ(string_value, "NO");
|
|
string_value.clear();
|
|
EXPECT_TRUE(list.GetEnumString("FORCED", &string_value));
|
|
EXPECT_EQ(string_value, "NO");
|
|
EXPECT_TRUE(list.GetEnumString("INSTREAM-ID", &string_value));
|
|
EXPECT_EQ(string_value, "CC1");
|
|
EXPECT_TRUE(list.GetQuotedString("CHARACTERISTICS", &string_value));
|
|
EXPECT_EQ(string_value, characteristics);
|
|
EXPECT_TRUE(list.GetQuotedString("CHANNELS", &string_value));
|
|
EXPECT_EQ(string_value, "1/2/4/7");
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, BadParse_MissingValue) {
|
|
HlsAttributeList list;
|
|
EXPECT_FALSE(list.Parse("A=,B=2,C=3"));
|
|
EXPECT_FALSE(list.Parse("A=1,B=,C=3"));
|
|
EXPECT_FALSE(list.Parse("A=1,B=2,C="));
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, BadParse_BadWhitespace) {
|
|
HlsAttributeList list;
|
|
EXPECT_FALSE(list.Parse("KEY=THIS VALUE"));
|
|
EXPECT_FALSE(list.Parse("THIS KEY=1"));
|
|
EXPECT_FALSE(list.Parse(" A=1,B=2"));
|
|
EXPECT_FALSE(list.Parse("A =1,B=2"));
|
|
EXPECT_FALSE(list.Parse("A= 1,B=2"));
|
|
EXPECT_FALSE(list.Parse("A=1 ,B=2"));
|
|
EXPECT_FALSE(list.Parse("A=1, B=2"));
|
|
EXPECT_FALSE(list.Parse("A=1,B =2"));
|
|
EXPECT_FALSE(list.Parse("A=1,B= 2"));
|
|
EXPECT_FALSE(list.Parse("A=1,B=2 "));
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, BadParse_BadQuotes) {
|
|
HlsAttributeList list;
|
|
EXPECT_FALSE(list.Parse("\"KEY\"=VALUE"));
|
|
EXPECT_FALSE(list.Parse("KEY=\"VALUE"));
|
|
EXPECT_FALSE(list.Parse("KEY=VALUE\""));
|
|
EXPECT_FALSE(list.Parse("KEY=\"VALUE\"AND"));
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, Serialize) {
|
|
HlsAttributeList list;
|
|
|
|
EXPECT_TRUE(list.SetInteger("INSTREAM-ID", 32));
|
|
EXPECT_TRUE(list.SetFloat("FRAME-RATE", 29.97));
|
|
EXPECT_TRUE(list.SetEnumString("METHOD", "AES-128"));
|
|
EXPECT_TRUE(list.SetQuotedString("VERSION", "1/2/5"));
|
|
EXPECT_TRUE(list.SetHexSequence("IV", a2b_hex("DEADBEAF")));
|
|
EXPECT_TRUE(list.SetResolution("RESOLUTION", 1920, 1080));
|
|
|
|
// Note: The HlsAttributeList class does not guarantee any particular
|
|
// order when serializing to a string.
|
|
const std::vector<std::string> kExpectedParts = {
|
|
"FRAME-RATE=29.97", "INSTREAM-ID=32",
|
|
// Note: HlsAttributeList uses lower prefix "0x" for hex sequences.
|
|
"IV=0xDEADBEAF", "METHOD=AES-128", "RESOLUTION=1920x1080",
|
|
"VERSION=\"1/2/5\""};
|
|
const std::string result = list.Serialize();
|
|
ASSERT_FALSE(result.empty());
|
|
|
|
size_t expected_length = kExpectedParts.size() - 1; // Start with commas.
|
|
for (const auto& part : kExpectedParts) {
|
|
ASSERT_TRUE(StringContains(result, part)) << "result: " << result;
|
|
expected_length += part.size();
|
|
}
|
|
EXPECT_EQ(expected_length, result.size()) << "result: " << result;
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, Serialize_Empty) {
|
|
HlsAttributeList list;
|
|
EXPECT_EQ(list.Serialize(), "");
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, Serialize_One) {
|
|
HlsAttributeList list;
|
|
EXPECT_TRUE(list.SetInteger("INSTREAM-ID", 32));
|
|
EXPECT_EQ(list.Serialize(), "INSTREAM-ID=32");
|
|
}
|
|
|
|
TEST(HlsAttributeListTest, Serialize_QuotedEmpty) {
|
|
HlsAttributeList list;
|
|
EXPECT_TRUE(list.SetQuotedString("VERSION", ""));
|
|
EXPECT_EQ(list.Serialize(), "VERSION=\"\"");
|
|
}
|
|
} // namespace test
|
|
} // namespace wvutil
|