7 #include "packager/file/udp_options.h"
9 #include <gflags/gflags.h>
11 #include "packager/base/strings/string_number_conversions.h"
12 #include "packager/base/strings/string_split.h"
14 DEFINE_string(udp_interface_address,
16 "IP address of the interface over which to receive UDP unicast"
17 " or multicast streams");
26 kInterfaceAddressField,
27 kMulticastSourceField,
32 struct FieldNameToTypeMapping {
33 const char* field_name;
37 const FieldNameToTypeMapping kFieldNameTypeMappings[] = {
38 {
"buffer_size", kBufferSizeField},
39 {
"interface", kInterfaceAddressField},
40 {
"reuse", kReuseField},
41 {
"source", kMulticastSourceField},
42 {
"timeout", kTimeoutField},
45 FieldType GetFieldType(
const std::string& field_name) {
46 for (
size_t idx = 0; idx < arraysize(kFieldNameTypeMappings); ++idx) {
47 if (field_name == kFieldNameTypeMappings[idx].field_name)
48 return kFieldNameTypeMappings[idx].field_type;
53 bool StringToAddressAndPort(base::StringPiece addr_and_port,
59 const size_t colon_pos = addr_and_port.find(
':');
60 if (colon_pos == base::StringPiece::npos) {
63 *addr = addr_and_port.substr(0, colon_pos).as_string();
65 if (!base::StringToUint(addr_and_port.substr(colon_pos + 1), &port_value) ||
66 (port_value > 65535)) {
76 base::StringPiece udp_url) {
77 std::unique_ptr<UdpOptions> options(
new UdpOptions);
79 const size_t question_mark_pos = udp_url.find(
'?');
80 base::StringPiece address_str = udp_url.substr(0, question_mark_pos);
82 if (question_mark_pos != base::StringPiece::npos) {
83 base::StringPiece options_str = udp_url.substr(question_mark_pos + 1);
85 base::StringPairs pairs;
86 if (!base::SplitStringIntoKeyValuePairs(options_str,
'=',
'&', &pairs)) {
87 LOG(ERROR) <<
"Invalid udp options name/value pairs " << options_str;
90 for (
const auto& pair : pairs) {
91 switch (GetFieldType(pair.first)) {
92 case kBufferSizeField:
93 if (!base::StringToInt(pair.second, &options->buffer_size_)) {
94 LOG(ERROR) <<
"Invalid udp option for buffer_size field "
99 case kInterfaceAddressField:
100 options->interface_address_ = pair.second;
102 case kMulticastSourceField:
103 options->source_address_ = pair.second;
104 options->is_source_specific_multicast_ =
true;
108 if (!base::StringToInt(pair.second, &reuse_value)) {
109 LOG(ERROR) <<
"Invalid udp option for reuse field " << pair.second;
112 options->reuse_ = reuse_value > 0;
116 if (!base::StringToUint(pair.second, &options->timeout_us_)) {
117 LOG(ERROR) <<
"Invalid udp option for timeout field "
123 LOG(ERROR) <<
"Unknown field in udp options (\"" << pair.first
130 if (!FLAGS_udp_interface_address.empty()) {
131 LOG(WARNING) <<
"--udp_interface_address is deprecated. Consider switching "
132 "to udp options instead, something like "
133 "udp:://ip:port?interface=interface_ip.";
134 options->interface_address_ = FLAGS_udp_interface_address;
137 if (!StringToAddressAndPort(address_str, &options->address_,
139 LOG(ERROR) <<
"Malformed address:port UDP url " << address_str;